IntentService源码

488 阅读3分钟

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

IntentService属于Service

IntentService继承自Service,那么它的结构就和Service一样。
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的源码不多就只有百来行
image.png
解析下这里的代码:
出现Looper和Handler。

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

  • Looper 在后面涉及到会介绍

IntentService的onCreate()方法

都知道Service和Activity类似都会有相关生命周期的方法。当上门的代码开启服务,系统就会调用Service的onCreate()
image.png
通过onCreat()方法可以得出下边的结论:

  • HandlerThread 一个线程类开启一个工作线程
  • mServiceLooper为工作线程的Looper
  • ServiceHandler为工作线程的Handler
    首先Handler是主线程的Handler还是工作线程的Handler主要看它的Looper,而ServiceHandler的Looper为工作线程下的Looper,所以ServiceHandler属于工作线程的Handler。判断哪个线程的Handler,主要因为看handlerMessage()方法在哪个线程执行。
    其次为什么说mServiceLooper为工作线程的Looper,
    image.png
    截图是HandlerThread的run()方法。可以看到mServiceLooper是在run()里面得到的,所以mServiceLooper为工作线程的Looper.。
    HandlerThread 一个线程类这个就不用说了。

HandlerThread

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

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

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