IntentService源码

分析的IntentService源码为API-25版本

IntentService属于Service

它可用于执行后台耗时任务,当任务执行完成后它会自动停止,在资源不足时,系统会对一些被认为时无用的资源给清理掉,由于它是 Service 的原因,它的优先级比单纯的线程的优先级很多,不容易被系统杀死(清理掉),所以它适合执行一些高优先级的后台任务。在实现上,IntentService 封装了 Handlerhread 和 Handler。
IntentService继承自Service,那么它的结构就和Service一样。

IntentService源码_第1张图片
image.png

这个不需多讲。但在使用上与Service有点不同,可以说简化版的Service。有点类似Handler与AsyTask的关系。

IntentService的使用

Intent serviceIntent = new Intent(this, ParseIntentService.class);
        startService(serviceIntent);

上面代码就是开启一个IntentService服务。开启之后就不用管理它了。这就是刚才说的简化版的Service。这篇文章的重点其实就是这里:IntentService为什么是简化的Service
上面的ParseIntentService继承IntentService,重写了onHandleIntent()方法。

IntentService源码

IntentService的源码不多就只有百来行


IntentService源码_第2张图片
image.png

解析下这里的代码:
出现Looper和Handler。

  • ServiceHandler handleMessage()方法,调用完onHandleIntent();方法后stopSelf()即停止服务。所以上面说IntentService开启服务后不需要管它,因为它调用完ServiceHandler的handleMessage()方法后就会停止服务。
    都知道Handler的handleMessage()不是Handler自己调用的,是有发送信息,handleMessage()就会被调用。那么现在看看哪里发送信息。

  • Looper 在后面涉及到会介绍

IntentService的onCreate()方法

都知道Service和Activity类似都会有相关生命周期的方法。当上门的代码开启服务,系统就会调用Service的onCreate()


IntentService源码_第3张图片
image.png

通过onCreat()方法可以得出下边的结论:

  • HandlerThread 一个线程类开启一个工作线程
  • mServiceLooper为工作线程的Looper
  • ServiceHandler为工作线程的Handler
    首先Handler是主线程的Handler还是工作线程的Handler主要看它的Looper,而ServiceHandler的Looper为工作线程下的Looper,所以ServiceHandler属于工作线程的Handler。判断哪个线程的Handler,主要因为看handlerMessage()方法在哪个线程执行。
    其次为什么说mServiceLooper为工作线程的Looper,
    IntentService源码_第4张图片
    image.png

    截图是HandlerThread的run()方法。可以看到mServiceLooper是在run()里面得到的,所以mServiceLooper为工作线程的Looper.。
    HandlerThread 一个线程类这个就不用说了。

HandlerThread

该类其实是干嘛的呢?简单来说,它就是帮我们创建一个工作线程的Looper,Looper的作用就是轮询我们的消息分发机制(这里不细说,细说又是一篇了。。。)。详细了解HandlerThread 可以看下面这篇文章
为什么要用HandlerThread,怎么用?

为什么出现Handler,Looper这些消息分发类别的类?

IntentService源码_第5张图片
image.png

主要因为IntentService的onStart()方法中发送了消息,上面创建onCreat()时,构建了ServiceHandler对象。通过Handler消息分发机制,处理抽象方法onHandleIntent();

使用IntentService,重写onHandleIntent()方法

  • 第一,创建一个类继承IntentService,实现onHandleIntent();
public class ParseIntentService extends IntentService {
 
    public ParseIntentService() {
        super("ParseIntentService");
    }

    /**
     * 该方法在工作线程上调用
     * */
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        //TODO 需要在服务做的事情
                    }
                });
    }
}
  • 第二,创建Intent,调用startService()方法。
Intent serviceIntent = new Intent(this, ParseIntentService.class);
        startService(serviceIntent);

总结

  • onHandleIntent()方法是在工作线程上的;不用执行更新UI的工作
  • IntentService里面已经有工作线程无需开启新的工作线程。
    这里想说一下:如果你在onHandleIntent()通过Retrofit调用接口,而又使用OkHttp的,建议使用Service不建议用IntentService。因为OkHttp已经帮我们创建了工作线程。这样又用IntentService的工作线程又用IntentService实际上是一种内存消耗。
  • 这点给自己一个笔记通过这个IntentService最主要认识了在工作线程中的Handler;HandlerThread管理工作线程的Looper
使用IntentService

你可能感兴趣的:(IntentService源码)