Android中IntentService的原理及使用

        在Android开发中,我们或许会碰到这么一种业务需求,一项任务分成几个子任务,子任务按顺序先后执行,子任务全部执行完后,这项任务才算成功。那么,利用几个子线程顺序执行是可以达到这个目的的,但是每个线程必须去手动控制,而且得在一个子线程执行完后,再开启另一个子线程。或者,全部放到一个线程中让其顺序执行。这样都可以做到,但是,如果这是一个后台任务,就得放到Service里面,由于Service和Activity是同级的,所以,要执行耗时任务,就得在Service里面开子线程来执行。那么,有没有一种简单的方法来处理这个过程呢,答案就是IntentService。

        IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。

       所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。

那么,用IntentService有什么好处呢?首先,我们省去了在Service中手动开线程的麻烦,第二,当操作完成时,我们不用手动停止Service,第三,it's so easy to use!

  下面我们来看个例子:

在main.xml文件中:

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:paddingBottom="@dimen/activity_vertical_margin"
 6     android:paddingLeft="@dimen/activity_horizontal_margin"
 7     android:paddingRight="@dimen/activity_horizontal_margin"
 8     android:paddingTop="@dimen/activity_vertical_margin"
 9     tools:context=".MainActivity" >
10 
11     <Button
12         android:id="@+id/button1"
13         android:layout_width="fill_parent"
14         android:layout_height="wrap_content" 
15         android:text="下载图片" />
16 
17 </RelativeLayout>

在MainActivity.java文件中:

 1 public class MainActivity extends Activity {
 2 
 3     private Button button;
 4     
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9         button = (Button) findViewById(R.id.button1);
10         button.setOnClickListener(new OnClickListener() {
11             
12             public void onClick(View v) {
13                 // TODO 自动生成的方法存根
14                 Intent service = new Intent(MainActivity.this, IntentSer.class);
15                 startService(service);
16             }
17         });
18     }
19 
20     @Override
21     public boolean onCreateOptionsMenu(Menu menu) {
22         // Inflate the menu; this adds items to the action bar if it is present.
23         getMenuInflater().inflate(R.menu.main, menu);
24         return true;
25     }
26 
27 }

在IntentSer.java文件中:

 1 public class IntentSer extends IntentService {
 2 
 3     private String path_url = "http://t1.ituba.cc/uploads/allimg/c101201/12911X4Fb460-2E024.jpg";
 4     
 5     
 6     public IntentSer() {
 7         super("IntentSer");
 8         // TODO 自动生成的构造函数存根
 9     }
10 
11     @Override
12     protected void onHandleIntent(Intent intent) {
13         // TODO 自动生成的方法存根
14         
15         File file = new File(this.getFilesDir(),"service.png");
16         try {
17             FileOutputStream outputStream = new FileOutputStream(file);
18             
19             InputStream inputStream = new URL(path_url).openStream();
20             byte[] buffer = new byte[1024];
21             int len = -1;
22             while((len = inputStream.read(buffer)) != -1){
23                 outputStream.write(buffer, 0, len);
24             }
25             outputStream.close();
26             inputStream.close();
27         } catch (FileNotFoundException e) {
28             // TODO 自动生成的 catch 块
29             e.printStackTrace();
30         } catch (MalformedURLException e) {
31             // TODO 自动生成的 catch 块
32             e.printStackTrace();
33         } catch (IOException e) {
34             // TODO 自动生成的 catch 块
35             e.printStackTrace();
36         }
37         
38     }
39     
40 
41 }

在AndroidManifest.xml文件中记得加网络权限:

<uses-permission android:name="android.permission.INTERNET"/>

由于IntentService继承于Service,所以要配置环境:

 <service android:name=".IntentSer"></service>

运行结果:

 

 

posted @ 2016-05-07 13:17  SoulCode  阅读(3823)  评论(0编辑  收藏  举报