IntentService源码解析
2021/4/13 20:27:20
本文主要是介绍IntentService源码解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
近期在做启动优化的时候用到了IntentService,就是把初始化的一些功能搬到IntentService里去延迟处理,加快了启动的时间,因此记录下IntentService内部的实现原理
一、IntentService有哪些特点
- 业务逻辑在子线程执行
- 多个任务不能并行执行,依次执行
- 所有的任务都执行完自定停止服务,不需要手动处理
二、如何使用
- 继承IntentService,实现onHandleIntent方法,同时也要实现构造函数
- 在清单文件注册
- 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源码解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-22怎么通过控制台去看我的页面渲染的内容在哪个文件中呢-icode9专业技术文章分享
- 2024-12-22el-tabs 组件只被引用了一次,但有时会渲染两次是什么原因?-icode9专业技术文章分享
- 2024-12-22wordpress有哪些好的安全插件?-icode9专业技术文章分享
- 2024-12-22wordpress如何查看系统有哪些cron任务?-icode9专业技术文章分享
- 2024-12-21Svg Sprite Icon教程:轻松入门与应用指南
- 2024-12-20Excel数据导出实战:新手必学的简单教程
- 2024-12-20RBAC的权限实战:新手入门教程
- 2024-12-20Svg Sprite Icon实战:从入门到上手的全面指南
- 2024-12-20LCD1602显示模块详解
- 2024-12-20利用Gemini构建处理各种PDF文档的Document AI管道