每天一篇系列:
强化知识体系,查漏补缺。
欢迎指正,共同学习!
IntentService是一个Android基础类,用于处理Intent类型的异步任务请求。当客户端调用android.content.Context#startService(Intent)发送请求时,Service服务被启动,且在其内部构建一个工作线程来处理Intent请求。当工作线程执行结束,Service服务会自动停止。
IntentService是一个抽象类,用户必须实现一个子类去继承它,且必须实现IntentService里面的抽象方法onHandleIntent来处理异步任务请求。
public class DownLoadService extends IntentService {
public static final String TAG = "DownLoadService";
//重写默认的构造方法
public DownLoadService() {
super("DownLoadService");
}
//在后台线程执行
@Override
protected void onHandleIntent(Intent intent) {
int key = intent.getIntExtra("key", 0);
String value = intent.getStringExtra("value");
switch (key) {
case 1:
//模拟耗时任务1
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
case 2:
//模拟耗时任务1
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
default:
break;
}
Log.e(TAG, "\nthe current time is: " + System.currentTimeMillis()/1000
+ "\nthe Thread id is " + Thread.currentThread().getId()
+ "\nthe current task is " + value);
}
}
IntentService源码分析:
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
public IntentService(String name) {
super();
mName = name;
}
...
}
首先IntentService继承了Service,生命周期还是从OnCreat,onStartCommand/onBind,onDestroy。只不过IntentService重写了这些方法,在子类中不需要再重写。
@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 thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
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);
}
}
protected abstract void onHandleIntent(Intent intent);
在onCreate()阶段,创建了HandlerThread,并且创建了一个Handler,Handler的Looper是HandlerThread的Looper。这样处理的话相当于创建一个带有消息队列的线程,耗时操作可以在HandlerThread这条线程中处理。可以看到Handler的消息都传递给onHandleIntent,而onHandleIntent是一个抽象方法,需要子类重写。这样也就是把耗时操作放置在HandlerThread线程中,用户可以重写onHandleIntent实现耗时操作处理,处理完毕后调用:
stopSelf(msg.arg1);
public final void stopSelf() {
stopSelf(-1);
}
public final void stopSelf(int startId) {
if (mActivityManager == null) {
return;
}
try {
mActivityManager.stopServiceToken(
new ComponentName(this, mClassName), mToken, startId);
} catch (RemoteException ex) {
}
}
等待耗时操作处理完毕以后,IntentService就会自动退出,生命周期终止。
IntentService借助HandlerThread来完成了异步消息的处理,那么HandlerThread和Thread有什么区别呢?
HandlerThread handlerThread = new HandlerThread("test");
handlerThread.start();
HandlerThread源码分析:
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
...
}
HandlerThread继承于Thread,Thread内部肯定有run()方法,看看HandlerThread内部的run实现:
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
果然没错,可以看到调用start的时候,run函数开始执行:
Looper.prepare();
多么熟悉的代码,还记得之前文章中分析的嘛,UI线程不也是这样创建Looper的。
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
在run方法里面新建了一个Looper,并且同步了notifyAll()通知Looper创建完了。
接下来:
onLooperPrepared();
Looper.loop();
最重要的是Looper.loop()这个方法,在Hander机制中我分析过,是不断的从MessageQueue中获取消息让后分发给指定的Handler。
Handler创建完后,需要和Handler绑定,这样才能消息处理,创建指定Looper的Handler:
Handler mHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
//实现自己的消息处理
return true;
}
});
在HandlerThread创建成功后,通过getLooper就可以获得Looper对象,因此Handler,Looper,MessageQueue就完成了消息事件机制。
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
到这里,其实就可以总结出HandlerThread和Thread的差别了,HandlerThread在Thread的基础上添加了一个Looper+Handler,在有消息时分发消息处理,没有消息时阻塞式等待消息而不是退出。Thread在处理完耗时操作后就会退出线程。
IntentService借助HandlerThread来区别Service,在新的工作线程中来处理耗时任务,好处也就不言而喻了吧。