黑马程序员技术交流社区

标题: 【济南校区】凯哥兵法之IntentService [打印本页]

作者: 孟凡凯老师    时间: 2016-5-24 22:00
标题: 【济南校区】凯哥兵法之IntentService
【济南校区】凯哥兵法之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停下来。

作者: liujian5461267    时间: 2016-6-1 18:34
西安好大的雨啊啊啊
作者: yanghong    时间: 2016-6-1 19:18
各位大神相互多交流学习
作者: 探花小李    时间: 2016-6-1 19:47
好久没来了,飘过~~~
作者: 红豆蓝    时间: 2016-6-1 20:04
每天都要来这里
作者: lizhoubin    时间: 2016-6-1 21:53
我来过,轻轻的.
作者: HuaMuLan    时间: 2016-6-1 21:55
加油加油加油
作者: 黎贵福    时间: 2016-6-1 22:05
一定努力
作者: 翻滚吧!大牛!    时间: 2016-6-1 22:08
好好加油
作者: chexinxin    时间: 2016-6-1 22:22
2016年6月1日 星期三
今天主要进行做题,准备后天的点招面试
作者: BaronZhang    时间: 2016-6-1 22:24
签个到..
作者: 孟凡凯老师    时间: 2016-6-1 22:28
chexinxin 发表于 2016-6-1 22:22
2016年6月1日 星期三
今天主要进行做题,准备后天的点招面试

加油!!
作者: 孟凡凯老师    时间: 2016-6-1 22:28
chexinxin 发表于 2016-6-1 22:22
2016年6月1日 星期三
今天主要进行做题,准备后天的点招面试

加油!!
作者: 孟凡凯老师    时间: 2016-6-1 22:29
liujian5461267 发表于 2016-6-1 14:24
签到了~~花花在哪里?


作者: 孟凡凯老师    时间: 2016-6-1 22:30
jeremyl 发表于 2016-6-1 17:57
签到了,一起加油哦

加油!
作者: 孟凡凯老师    时间: 2016-6-1 22:30
liujian5461267 发表于 2016-6-1 18:34
西安好大的雨啊啊啊

出门记得带伞!
作者: 孟凡凯老师    时间: 2016-6-1 22:30
wy123580 发表于 2016-6-1 20:11
签到!!!自己好久没签到了,马上点招了,好担心!!!

只要准备充足就能过的!
作者: static小白    时间: 2016-6-1 22:35
虽然看不懂,但是也学习下
作者: 戎马生涯    时间: 2016-6-1 22:40
学习了!努力中~~
作者: ddong1031    时间: 2016-6-1 22:44
学习了,努力 努力 !!
作者: zxjuzhu    时间: 2016-6-1 22:58
努力学习中!
作者: vvvvvc    时间: 2016-6-1 23:05
qiandao...................
作者: java25    时间: 2016-6-1 23:09
学到后面感觉好吃力
作者: 378193763    时间: 2016-6-1 23:15
今天的东西好多...幸亏复习了
作者: yesnowoshiqiang    时间: 2016-6-1 23:18
越听约迷糊呢,希望楼主说的再详细一些
作者: 1046656214    时间: 2016-6-1 23:19
感觉有点不好理解,还是基础不好啊,加强基础,再来学习
作者: cxc0603    时间: 2016-6-1 23:23
今天的东西好多...幸亏复习了
作者: 1046656214    时间: 2016-6-1 23:31
先签个到,赞继续逛逛,拣点漏
作者: huhemingtiancai    时间: 2016-6-1 23:45
赞一个!!!
作者: java25    时间: 2016-6-1 23:49
签     到。。
作者: yourlike    时间: 2016-6-1 23:49
!!!!!顶一个
作者: 孟凡凯老师    时间: 2016-6-1 23:50
18634319112 发表于 2016-6-1 22:39
签到,这些都不懂,还是看看吧

学了Android就知道啦!
作者: 孟凡凯老师    时间: 2016-6-1 23:52
378193763 发表于 2016-6-1 23:15
今天的东西好多...幸亏复习了

每天的学习量都是比较大的,经常会出现学完过两天就忘记之前的知识了,所以就要求我们要时常的去复习!
作者: 孟凡凯老师    时间: 2016-6-2 00:01
yesnowoshiqiang 发表于 2016-6-1 23:18
越听约迷糊呢,希望楼主说的再详细一些

简单来说: Servive是运行在UI线程中,不建议做耗时操作,IntentService作为Service的子类内部提供了HandlerThread,可以做耗时操作。Service在Android课程中有具体讲解。
作者: nanliner    时间: 2016-6-2 00:13
加油加油加油
作者: 一架飞机CE3    时间: 2016-6-2 00:48
加油加油 大家一起加油
作者: 善良的死神达乐    时间: 2016-6-2 00:58
啥情况????为什么觉得不懂了???
作者: wsl123456    时间: 2016-6-2 07:09
早早的,来签个到,新的一天,继续加油
作者: ZhengJingFeng    时间: 2016-6-2 07:42
什么情况,看不懂啊
作者: SkyBlack    时间: 2016-6-2 08:29
假装看得懂的样子
作者: 一念地狱    时间: 2016-6-2 12:14
收藏了,学习一下
作者: 1046656214    时间: 2016-6-4 22:25
虽然看不太懂,但先读一遍,等到学到这个知识的时候,再拿出来研究吧
作者: 08期javaee-zmz    时间: 2016-6-5 21:45
棒棒的!赞赞!!!
作者: cliangtime    时间: 2016-6-14 20:38
虽然看不懂,但是也学习下
作者: 443785417    时间: 2016-6-14 22:51
lihai             厉害
作者: 戎马生涯    时间: 2016-6-15 20:59
不错!赞一个~~~




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2