IntentService源码解析

2021/4/13 20:27:20

本文主要是介绍IntentService源码解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

近期在做启动优化的时候用到了IntentService,就是把初始化的一些功能搬到IntentService里去延迟处理,加快了启动的时间,因此记录下IntentService内部的实现原理

一、IntentService有哪些特点

  1. 业务逻辑在子线程执行
  2. 多个任务不能并行执行,依次执行
  3. 所有的任务都执行完自定停止服务,不需要手动处理

二、如何使用

  1. 继承IntentService,实现onHandleIntent方法,同时也要实现构造函数
  2. 在清单文件注册
  3. startService 通过intent传入不同的标识,在onHandleIntent中获取不同标识并执行不行的任务
public class Demo extends IntentService {

    public Demo() {
        //给工作线程命名
        super("demoService");
    }

    //重写onHandleIntent方法
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        
    }
}

三、生命周期分析
多次启动IntentService并不会多次执行onCreate方法,onCreate只会执行一次,当有多个任务的时候启动多次IntentService会多次执行onStartCommand方法,当所有任务执行完毕会调用onDestroy方法。

四、IntentService内部原理

1.service启动时的处理

//IntentService
@Override
public void onCreate() {
     super.onCreate();
     //启动HandlerThread线程
     HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
     thread.start();
     //取到HandlerThread线程里的looper
     mServiceLooper = thread.getLooper();
     //创建handler,该handler的looper对象是子线程的
     mServiceHandler = new ServiceHandler(mServiceLooper);
}
//HandlerThread对象
public class HandlerThread extends Thread {
	Looper mLooper;
	//忽略其他方法
	@Override
    public void run() {
    	//可以看到这是一个子线程,在run方法里创建了looper,也同时创建了MessageQueue
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        //开启了loop循环 因此这个run方法会一直执行(除非looper停止)
        Looper.loop();
        mTid = -1;
    }
    //忽略其他方法
}

2.service收到执行任务的处理

public abstract class IntentService extends Service {
	
	private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
        	//handler的dispatchMessage之后就会调用该方法
        	//该方法会执行onHandleIntent,因此我们在使用IntentService的时候要重写onHandleIntent
            onHandleIntent((Intent)msg.obj);
            //msg.arg1是startId,这里为啥要传startId呢?
            //每次执行完startId都会去调用stopSelf,该方法会判断当前service是否还有
            //其他的任务没有执行,如果有就不会停止服务,如果没有其他任务了那么就停止服务
            stopSelf(msg.arg1);
        }
    }

	@Override
    public void onStart(@Nullable Intent intent, int startId) {
    	//每次新来的执行任务都会通过handler来处理,先放到消息队列里依次去执行
    	//每次的startId都不一样且都是大于0的,可以根据startId来为后期stopSelf时作为依据
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

	//多次启动service会执行多次onStartCommand方法
    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
    	//调用了onStart方法
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }
    
 	@WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

3.service停止

	@Override
    public void onDestroy() {
    	//service执行onDestroy的时候调用HandlerThread里的looper.quit方法
    	//这样HandlerThread的run方法就会执行完毕不会处于阻塞状态
        mServiceLooper.quit();
    }

五、总结
IntentService继承了Service,内部采用了handler+thread的方式来将需要执行的任务存放到MessageQueue,在thread里的run方法里不断的轮询消息,并通过onHandleIntent方法来通知调用者去处理,在每次执行完onHandleIntent后都会去判断一下当前是否还有等待执行的任务,如果没有的话那么就自动停止服务。



这篇关于IntentService源码解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程