IntentService剖析

IntentService的由来

众所周知service默认是运行在主线程中的,如果我们需要在service中进行耗时操作,往往我们的做法就是在serviceonStart方法中开启一个子线程,然后将耗时操作放到子线程中,但是service一旦开启,除非我们调用stopService或者stopSelf,服务才会停止,如何实现在service中直接进行耗时操作?如何实现service的即用即停呢?这是IntentService就横空出世了。我们来看下官方介绍:

the service is started as needed, handles each Intent in turn using a workerthread, and stops itself when it runs out of work.

IntentService会根据需求开启一个工作线程来处理这些需求,并且当所有的工作完成后关闭自身。

IntentService的使用

 1public class MyIntentService extends IntentService {
 2
 3    private static final String TAG ="MyIntentService";
 4
 5    public MyIntentService() {
 6        super("myIntentService");
 7    }
 8
 9    public MyIntentService(String name) {
10        super(name);
11    }
12
13    @Override
14    public void onCreate() {
15        super.onCreate();
16        Log.i(TAG, "onCreate");
17    }
18
19    @Override
20    public void onStart(@Nullable Intent intent, int startId) {
21        super.onStart(intent, startId);
22        Log.i(TAG, "onStart");
23    }
24
25
26    @Override
27    public void onDestroy() {
28        super.onDestroy();
29        Log.i(TAG, "onDestroy");
30    }
31
32    @Override
33    protected void onHandleIntent(@Nullable Intent intent) {
34        Log.i(TAG, "onHandleIntent start");
35        try {
36            Thread.sleep(3000);
37        } catch (InterruptedException e) {
38
39        }
40        Log.i(TAG, "onHandleIntent end");
41    }
42}
43
44//开启服务
45startService(new Intent(MainActivity.this,MyIntentService.class));

下面是输出结果:

MyIntentService: onCreate
MyIntentService: onStart
MyIntentService: onHandleIntent start
MyIntentService: onHandleIntent end
MyIntentService: onDestroy

Log输出中我们可以看出当任务完成以后,service调用onDestroy,也验证上面我们所说的当IntentService执行完任务后,会自动关闭。

IntentService源码解析

IntentService的使用中,我们可以看出其主要方法就是一个onHandleIntent,而耗时操作也将在onHandleIntent中执行。接下来我们看下onHandleIntent的调用流程

 1 private final class ServiceHandler extends Handler {
 2        public ServiceHandler(Looper looper) {
 3            super(looper);
 4        }
 5
 6        @Override
 7        public void handleMessage(Message msg) {
 8            onHandleIntent((Intent)msg.obj);
 9            stopSelf(msg.arg1);
10        }
11    }

可以看出来,IntentService中保存了一个Handler对象,而onHandleIntent方法的调用是在Handler的消息处理中,有处理消息的过程,必然也存在消息发送的过程,我们接下来看看消息发送的流程:

 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    }
 9
10    @Override
11    public void onStart(Intent intent, int startId) {
12        Message msg = mServiceHandler.obtainMessage();
13        msg.arg1 = startId;
14        msg.obj = intent;
15        mServiceHandler.sendMessage(msg);
16    }

整个流程就很明确了,在ServiceonStart方法中将传进来的intent作为消息的obj创建消息并发送。而在ServiceonCreate方法中创建了一个HandlerThread,并从中取出一个Looper对象作为Handler的参数创建了一个Handler对象,并使用这个Handler对象发送消息和处理消息。而这其中有一个陌生的类就是HandlerThread,我们来大胆预测下HandlerThread的源码实现。onHandleIntent中执行耗时操作,而onHandlerIntent又是在HandlerhandleMessage中调用,说明handler消息处理过程在子线程中执行,而handler消息处理又是在looperloop方法中被调用,说明创建handler对象传入的looper对象在子线程中创建,并调用了loop方法,我们来看下HandlerThread的源码看下是否和我们预想的是否一致?

 1 @Override
 2    public void run() {
 3        mTid = Process.myTid();
 4        Looper.prepare();
 5        synchronized (this) {
 6            mLooper = Looper.myLooper();
 7            notifyAll();
 8        }
 9        Process.setThreadPriority(mPriority);
10        onLooperPrepared();
11        Looper.loop();
12        mTid = -1;
13    }

可以看出和我们预想的一样的,在threadrun方法中调用Looper.prepare方法创建与当前子线程相关的Looper对象,并调用Looper.loop方法获取消息队列里面的消息。
好了,我们来梳理一下IntentService整个流程

  1. IntentServiceonCreate方法中创建一个HandlerThread线程并启动,HandlerThreadrun方法中创建一个Looper对象并开始loop消息,并将Looper对象作为参数创建Handler
  2. IntentServiceonStart方法中将传入的Intent作为Messageobj,并使用Handler发送。
  3. Handler接收到消息以后,调用handleMessage方法,将耗时操作转移到HandlerThread线程中。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值