ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

IntentService源码解析

2021-04-13 18:30:52  阅读:170  来源: 互联网

标签:onHandleIntent 执行 IntentService 源码 msg 解析 startId public


近期在做启动优化的时候用到了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后都会去判断一下当前是否还有等待执行的任务,如果没有的话那么就自动停止服务。

标签:onHandleIntent,执行,IntentService,源码,msg,解析,startId,public
来源: https://blog.csdn.net/qq_36356379/article/details/115673907

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有