IntentService也是属于Android异步线程模块的一部分,上一篇是HandlerThread的源码:
Android进阶2:线程和线程池(2)—— HandlerThread原理解析
如果对HandlerThread原理不太熟悉的,建议先看下我的上一篇文章HandlerThread的原理解析,因为IntentService内部使用的是HandlerThread。。。
先来看下IntentService的用法:
需求: 实现一个IntentService实现类,定义一个成员变量count, 开启线程,回调给UI主线程,
代码如下:
/**
* Created by ${liumengqiang} on 2018/8/2.
*/
public class TestIntentService extends IntentService {
private int count = 0;
private boolean isRunning = true;
public TestIntentService() {
super("TestIntentService");
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
while(isRunning) {
synchronized (this) {
if(count >= 10) {
isRunning = false;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count ++;
//发送广播
Intent intentBroadcast = new Intent();
intentBroadcast.putExtra("count", count+ "");
intentBroadcast.setAction("edu.jju.broadcastreceiver");
sendBroadcast(intentBroadcast);//发送普通广播
}
}
}
}
MainActivity代码:
public class TestBrodecast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String countString = intent.getStringExtra("count");
textView.setText(countString);
}
}
以上是IntentService的简单例子,接下来就看源码= -= ;
IntentService源码解析
1: 成员变量
private volatile Looper mServiceLooper; //Looper对象
private volatile ServiceHandler mServiceHandler; //运行在子线程的handler
private String mName; //工作线程的名称
private boolean mRedelivery; //服务销毁是是否重新创建,以及创建之后的状态。
从成员变量看出了:
- 有Looper对象
- 有handler对象
- mRedelivery对象?
前两个我们能嗅到handler的气息,但是这个mRedelivery是什么鬼? 是这样的,现在只能说是跟服务的销毁和重建有关。下文解释。
2: onCreate方法:
既然是IntentService,service的子类,肯定还是从onCreate方法说起:
@Override
public void onCreate() {
//注意点1:
// 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();
//注意点2:创建HandlerThread
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start(); //开启HandlerThread
mServiceLooper = thread.getLooper(); //获取子线程的Looper对象
mServiceHandler = new ServiceHandler(mServiceLooper); //实例化运行在子线程的handler
}
上述源码写了两个注意点:
- 上文Google给出的描述大致意思是:会启动一个子工作线程,并且通过静态启动服务(startService方法),此时将切换到子工作线程
- 注意2主要是之后的四行代码,可以看到,首先创建了HandlerThread对象,通过上篇博客知道了handlerThread也就是handler + Thread的封装,在这里使用HandlerThread说明:IntentService内部实际上原理使用的还是HandlerThread, 只不过此时的载体是Service。
通过上述代码可以看出,创建了HandlerThread, 再开启子线程,记住,此时子线程已经开启了,只不过还没有消息能够处理。通过上篇博客我们知道了其实mServiceHandler 是运行在子线程的。那么就有必要看下mServiceHandler的源码:
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); //任务完成,精确的销毁service
}
}
通过源码可以看书,ServiceHandler的内部逻辑很简单,就是先调用了onHandleIntent方法,等等?这个方法不就是我们开发者必须复写的方法嘛,因为ServiceHandler就是运行在子线程,所以onHandleIntent肯定也是在子线程啦,所以我们可以在onHandleIntent方法内做耗时操作。
通过onCreate方法描述,知道了必须通过startService启动服务,那么startService启动服务的流程,各位应该还记得吧?
3:startService启动服务
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId); //每次启动都会调用onStart方法
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage(); //新建消息对象
msg.arg1 = startId; //用于销毁service任务
msg.obj = intent; //传入Intent对象
mServiceHandler.sendMessage(msg); //发送消息
}
通过上述源码可以看出:调用onStartCommand每一次都会首先调用onStart方法,那么在onStart方法内,看到了Message,sendMessage发送消息是不是很熟悉了,然后在ServiceHandler的handleMessage方法中回调给开发者。
流程通了吧,在捋一下:
onCreate: 通过HandlerThread开启一个子线程,在子线程中运行的ServiceHandler中回调onHandleIntent方法交给开发者处理
onStart:在此方法内发送消息给子线程。
通过HandlerThread和IntentService的学习,我们知道内部根本的原理就是:handler, Looper, MessageQueue + Thread,所以通过在HandlerThread对象单一的情况下,无论发送多少的任务,都是顺序执行的,不会并发执行。
文中如有错误,欢迎指出,一边纠正 = - = 。
Android开发交流群:543671130