A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

【济南校区】凯哥兵法之IntentService

什么是IntentService?

IntentService是Service的子类,比普通的Service增加了额外的功能。先看Service本身存在两个问题:  
     1.  Service不会专门启动一条单独的进程,Service与它所在应用位于同一个进程中;  
     2.  Service也不是专门一条新线程,因此不应该在Service中直接处理耗时的任务;  

    官方的解释是:
  1. IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through android.content.Context.startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

  2. This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.

  3. All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
复制代码
意思是说:IntentService是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候). 所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求。

IntentService特征:
     1. 会创建独立的worker线程来处理所有的Intent请求;  
     2. 会创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程问题;  
     3. 所有请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service;  
     4. 为Service的onBind()提供默认实现,返回null;  
     5. 为Service的onStartCommand提供默认实现,将请求Intent添加到队列中;

IntentService的使用:
    1.  继承IntentService类,并重写onHandleIntent()方法
  1. public class MyIntentService extends IntentService {

  2.         public MyIntentService() {
  3.                 super("MyIntentService");
  4.         }
  5.         @Override
  6.         protected void onHandleIntent(Intent intent) {
  7.                 // IntentService会使用单独的线程来执行该方法的代码
  8.                 // 该方法内执行耗时任务,在这简单的让线程等待20秒        
  9.                 System.out.println("开始耗时操作....");
  10.                 SystemClock.sleep(200000);
  11.                 System.out.println("耗时操作结束....");
  12.         }
  13. }
复制代码
     2.在Activity中通startService(Intent)启动
  1. public class MainActivity extends Activity {   
  2.    
  3.      @Override   
  4.      protected void onCreate(Bundle savedInstanceState) {   
  5.           super.onCreate(savedInstanceState);   
  6.           setContentView(R.layout.activity_main);   
  7.      }   

  8.      public void startIntentService(View source) {   
  9.           // 创建需要启动的IntentService的Intent   
  10.           Intent intent = new Intent(this, MyIntentService.class);   
  11.           startService(intent);   
  12.      }   
  13. }   
复制代码

IntentService源码分析:
  1. public abstract class IntentService extends Service {

  2.      private volatile Looper mServiceLooper;
  3.      private volatile ServiceHandler mServiceHandler;
  4.      private String mName;
  5.      private boolean mRedelivery;

  6.      private final class ServiceHandler extends Handler {
  7.      public ServiceHandler(Looper looper) {
  8.           super(looper);
  9.      }
  10.    
  11.      @Override
  12.      public void handleMessage(Message msg) {
  13.           onHandleIntent((Intent)msg.obj);
  14.           stopSelf(msg.arg1);
  15.      }
复制代码
通过源码也可以看出IntentService是Service的子,实际上是Looper,Handler,Service 的集合体,他不仅有服务的功能,还有处理和循环消息的功能。
  1. @Override
  2. public void onCreate() {
  3.      super.onCreate();
  4.      HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
  5.      thread.start();
  6.      mServiceLooper = thread.getLooper();
  7.      mServiceHandler = new ServiceHandler(mServiceLooper);
  8. }
复制代码
从IntentService的onCreate()方法可以看出在创建的时候就会创建Handler线程(HandlerThread)并启动,然后再得到当前线程的Looper对象来初始化IntentService的mServiceLooper,接着创建mServicehandler对象。
  1. @Override
  2. public void onStart(Intent intent, int startId) {
  3.      Message msg = mServiceHandler.obtainMessage();
  4.      msg.arg1 = startId;
  5.      msg.obj = intent;
  6.      mServiceHandler.sendMessage(msg);
  7. }
复制代码
在IntentService启动的时候,就会创建一个Message对象并且附带startId和Intent,最终发送到MessageQueue中,接下来Looper发现MessageQueue中有Message的时候,Handler就会进行处理消息,接下来处理的代码如下:
  1.         @Override
  2.         public void handleMessage(Message msg) {
  3.              onHandleIntent((Intent)msg.obj);
  4.              stopSelf(msg.arg1);
  5.         }
复制代码
onHandleIntent((Intent)msg.obj),这是一个抽象的方法就是我们要重写实现的方法,我们可以在这个方法里面处理我们的工作.当任务完成时就会调用stopSelf(msg.arg1)这个方法来结束指定的工作,当所有的工作执行完后:就会执行onDestroy方法
  1.       @Override
  2.         public void onDestroy() {
  3.              mServiceLooper.quit();
  4.         }
复制代码
服务结束后调用这个方法 mServiceLooper.quit()使looper停下来。

45 个回复

正序浏览
不错!赞一个~~~
回复 使用道具 举报
lihai             厉害
回复 使用道具 举报
虽然看不懂,但是也学习下
回复 使用道具 举报
棒棒的!赞赞!!!
回复 使用道具 举报
虽然看不太懂,但先读一遍,等到学到这个知识的时候,再拿出来研究吧
回复 使用道具 举报
收藏了,学习一下
回复 使用道具 举报
假装看得懂的样子
回复 使用道具 举报
什么情况,看不懂啊
回复 使用道具 举报
早早的,来签个到,新的一天,继续加油
回复 使用道具 举报
啥情况????为什么觉得不懂了???
回复 使用道具 举报
加油加油 大家一起加油
回复 使用道具 举报
加油加油加油
回复 使用道具 举报
yesnowoshiqiang 发表于 2016-6-1 23:18
越听约迷糊呢,希望楼主说的再详细一些

简单来说: Servive是运行在UI线程中,不建议做耗时操作,IntentService作为Service的子类内部提供了HandlerThread,可以做耗时操作。Service在Android课程中有具体讲解。
回复 使用道具 举报 1 0
378193763 发表于 2016-6-1 23:15
今天的东西好多...幸亏复习了

每天的学习量都是比较大的,经常会出现学完过两天就忘记之前的知识了,所以就要求我们要时常的去复习!
回复 使用道具 举报
18634319112 发表于 2016-6-1 22:39
签到,这些都不懂,还是看看吧

学了Android就知道啦!
回复 使用道具 举报
!!!!!顶一个
回复 使用道具 举报
签     到。。
回复 使用道具 举报
赞一个!!!
回复 使用道具 举报
先签个到,赞继续逛逛,拣点漏
回复 使用道具 举报
今天的东西好多...幸亏复习了
回复 使用道具 举报
123下一页
您需要登录后才可以回帖 登录 | 加入黑马