在Android基础知识:多线程基础总结中除了AsyncTask
和HandlerThread
还提到了Android
提供的另一种进行异步任务的方式IntentService
。这一篇就来看看IntentService
的使用和运行原理。android
IntentService
的使用步骤分为如下几步:bash
1.继承实现IntentService抽象类,复写onHandleIntent方法markdown
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服务app
Intent intent = new Intent(this, MyIntentService.class); intent.putExtra("type", "type1"); startService(intent); 复制代码
运行结果: 异步
从使用方法上来看IntentService
与通常的Service
使用步骤也没啥区别,都是先建立实现一个Service
再到AndroidManifest.xml
中注册,最后启动服务便可。那么仍是从源码看看IntentService
到底有什么特别的地方。ide
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
类的实现。oop
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
将自身关闭。post
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关闭 |