1.前言
在Android基础知识:多线程基础总结中除了AsyncTask
和HandlerThread
还提到了Android
提供的另外一种进行异步任务的方式IntentService
。这一篇就来看看IntentService
的使用和运行原理。
2.IntentService的使用
IntentService
的使用步骤分为以下几步:
1.继承实现IntentService抽象类,复写onHandleIntent方法
public class MyIntentService extends IntentService {
private static final String TAG = "MyIntentService";
private int percent;
public MyIntentService() {
super("MyIntentServiceThread");
}
@Override
protected void onHandleIntent(Intent intent) {
String type = intent.getStringExtra("type");
switch (type) {
case "type1":
{
for (percent = 0; percent <= 100; percent += 10) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, Thread.currentThread().getName() + " type1 " + percent + "% progress");
}
Log.d(TAG, Thread.currentThread().getName() + ":finish");
}
break;
}
}
}
复制代码
2.在AndroidManifest.xml注册Service
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.thread.intentservice">
<application
.......
<service android:name=".MyIntentService" />
</application>
</manifest>
复制代码
3.启动IntentService服务
Intent intent = new Intent(this, MyIntentService.class);
intent.putExtra("type", "type1");
startService(intent);
复制代码
运行结果:
3.IntentService运行原理
从使用方法上来看IntentService
与一般的Service
使用步骤也没啥区别,都是先创建实现一个Service
再到AndroidManifest.xml
中注册,最后启动服务即可。那么还是从源码看看IntentService
到底有什么特别的地方。
public abstract class IntentService extends Service {
.......
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public IntentService(String name) {
super();
mName = name;
}
复制代码
首先看到IntentService
是个抽象类,并且继承自Service
,它的构造函数中只传入了name
,从注释看出就是工作线程的name
。既然是个Service
接着就看它生命周期中的onCreate
方法。
@Override
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
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
// 调用HandlerThread的start方法开启线程
thread.start();
// 获得HandlerThread中的Looper
mServiceLooper = thread.getLooper();
// 创建Handler
mServiceHandler = new ServiceHandler(mServiceLooper);
}
复制代码
onCreate
方法中的代码看着有些熟悉就是之前在Android进阶知识:HandlerThread相关中提到的HandlerThread
的使用步骤。所以说在onCreate
方法中就是创建了一个HandlerThread
的工作线程,调用了它的start
方法并且创建了对应Handler
。先来看一下这个ServiceHandler
类的实现。
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);
}
}
复制代码
ServiceHandler
是IntentService
的内部类,其实现也很简单,接收了传入的Looper
后复写handleMessage
方法,handleMessage
方法中收到消息后先调用了onHandleIntent
方法将intent
传入。onHandleIntent
方法是我们自己实现IntentService
时复写的方法,源码这里是个抽象方法,主要进行异步耗时任务,然后调用stopSelf
将自身关闭。
protected abstract void onHandleIntent(@Nullable Intent intent);
复制代码
接着继续按生命周期走到了onStartCommand
方法。
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
复制代码
onStartCommand
方法中又调用了onStart
方法,而onStart
方法创建了消息,并且将接收到的intent
作为消息的obj
,startId
传递给消息arg1
,最后调用mServiceHandler.sendMessage
将消息发送出去。到此整个IntentService
的运行流程就差不多了,最后在调用stopSelf
方法后服务会调用生命周期中的onDestory
方法,在IntentService
的onDestory
方法中会直接调用mServiceLooper.quit()
方法将Lopper
退出。
另外IntentService
中还有个mRedelivery
成员变量可以通过setIntentRedelivery
方法设置,用来决定onStartCommand
方法的返回值,从而决定服务在被异常杀死后是否自动重启该服务。
// 布尔值变量
private boolean mRedelivery;
// setIntentRedelivery方法
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
// onStartCommand返回值
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
复制代码
4.总结
从上面的阅读的源码可以知道IntentService
实现异步任务是基于HandlerThread
实现的。
IntentService的运行流程: 启动服务后会先进行生命周期的onCreate
方法,方法中创建HandlerThread
和ServiceHandler
,接着进入生命周期的onStartCommand
方法,onStartCommand
方法中调用onStart
方法,onStart
方法使用ServiceHandler
发送消息,handleMessage
方法中接收到消息,调用复写的onHandleIntent
方法,最后调用stopSelf
方法关闭自己。
IntentService与普通Service对比:
普通Service | IntentService |
---|---|
运行在主线程 | 运行在创建的工作线程 |
需要手动调用stopService关闭 | 自动调用stopSelf关闭 |