Android IntentService源码分析
<h2>简介</h2> <p>Service 是 Android 四大组件之一,用于后台运行,但由于 Service 依然运行在主线程,所以是不能直接进行耗时操作的。如果有耗时操作,还是需要放到子线程中,可以手动开启线程,也可以使用 Android 提供的一个非常简便的类 IntentService 。这个类的源码还是很简单的,本文分析一下它的实现。</p> <h2>HandlerThread</h2> <p>在分析 IntentService 之前,先要了解 HandlerThread 。看名字就知道这个类是与 Handler 有关的线程类,API 是这么描述的:</p> <p>Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.</p> <p>它是为创建附带 Looper 对象的线程的帮助类。 Looper 对象可用于创建 Handler 类。 当然仍然要调用 start() 来开启线程。</p> <p>在上篇文章 <a href="/misc/goto?guid=4959670011941923907" rel="nofollow,noindex">Android Handler的原理</a> 中,我们知道一个线程创建 Handler 的时候,必须要有 Looper 对象,利用 Looper 开启消息循环。在主线程中,系统已经帮我们做了这些工作。那么如果在其它子线程,我们该怎么创建 Looper 呢? 看看 HandlerThread 的 run() 方法:</p> <pre> <code class="language-java">public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; }</code></pre> <p>在这个方法中调用了 Looper.prepare() 为线程获取 Looper 对象,并且保存这个对象。接着又调用 Looper.loop() 开启消息循环,这个方法里面有个无限循环不断从消息队列中取出消息,于是这个线程的消息系统便建立起来了。这些在上一篇文章中已经分析过。</p> <h2>IntentService</h2> <p>搞清楚 HandlerThread , IntentService 就很简单了。 IntentService 内部使用了 HandlerThread 。 IntentService 继承了 Service 并且是 一个抽象类。下面是它的 onCreate() 方法:</p> <pre> <code class="language-java"> public void onCreate() { // TODO: It would be nice to have an option to hold a partial wakelock // during processing, and to have a static startService(Context, Intent) // method that would launch the service & hand off a wakelock. super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } } </code></pre> <p>这个方法里面创建了一个 HandlerThread 对象,并且获取它的 Looper ,紧接着用这个 Looper 创建了 Handler 。 IntentService 的 handleMessage 方法把接收的消息交给 onHandleIntent 处理,这个方法是一个抽象方法,也是我们使用 IntentService 时需要重写的方法。 onHandleIntent 处理完成后 IntentService 会调用 stopSelf() 自动停止。 handleMessage 将在 Looper.loop() 方法中被调用,运行在 HandlerThread 中,所以可以安全地处理耗时操作。</p> <p>消息又是怎么传过来的呢?看一下 onStartCommand() 的源码:</p> <pre> <code class="language-java">public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }</code></pre> <p>很简单,把 intent 参数包装到 message 的 obj 中,然后发送消息。这里的 Intent 就是启动服务时 startService(Intent) 里的 Intent 。</p> <p>对于 Service 而言,多次调用 startService(Intent) 时, onCreate() 方法只会调用一次,所以在这里面做一些初始化工作,而 onStartCommand 则相应地会调用多次。因此,只要 Intent 的参数不同,便可以完成不同的任务。</p> <h2>总结</h2> <p>从上面的分析可以看出,只要明白 Handler 的原理, IntentService 还是比较好理解的。使用 IntentService 需要注意几点:</p> <ul> <li> <p>不可以直接和UI做交互。为了把他执行的结果体现在UI上,需要把结果返回给Activity。</p> </li> <li> <p>工作任务队列是顺序执行的,如果一个任务正在IntentService中执行,此时你再发送一个新的任务请求,这个新的任务会一直等待直到前面一个任务执行完毕才开始执行。</p> </li> <li> <p>正在执行的任务无法打断。</p> </li> </ul> <p>来自: <a href="/misc/goto?guid=4959670012033158841" rel="nofollow">https://segmentfault.com/a/1190000004875002</a></p>
本文由用户 aqpp1310 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
转载本站原创文章,请注明出处,并保留原始链接、图片水印。
本站是一个以用户分享为主的开源技术平台,欢迎各类分享!