在Android基础知识:多线程基础总结中除了AsyncTask
和HandlerThread
还提到了Android
提供的另一种进行异步任务的方式IntentService
。这一篇就来看看IntentService
的使用和运行原理。android
IntentService
的使用步骤分为如下几步:bash
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注册Serviceapp
<?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);
复制代码
运行结果: ide
从使用方法上来看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
方法。oop
@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
类的实现。post
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
将自身关闭。ui
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;
}
复制代码
从上面的阅读的源码能够知道IntentService
实现异步任务是基于HandlerThread
实现的。
IntentService的运行流程: 启动服务后会先进行生命周期的onCreate
方法,方法中建立HandlerThread
和ServiceHandler
,接着进入生命周期的onStartCommand
方法,onStartCommand
方法中调用onStart
方法,onStart
方法使用ServiceHandler
发送消息,handleMessage
方法中接收到消息,调用复写的onHandleIntent
方法,最后调用stopSelf
方法关闭本身。
IntentService与普通Service对比:
普通Service | IntentService |
---|---|
运行在主线程 | 运行在建立的工做线程 |
须要手动调用stopService关闭 | 自动调用stopSelf关闭 |