異步處理技術(一)
寫在前面
本文章為《Android高級進階》的讀書筆記,看過的朋友可以出門轉(zhuǎn)去別的更深度的文章了,沒看過的可以當作知識點來看一下,歡迎給意見進行知識交流。表達能力有限,不喜勿噴。
安卓定義的三種線程:
-
主線程:
主線程就是我們熟悉的UI線程,謹記只有UI線程才成操作控件更新空間。想子線程任務完成更新界面的方法現(xiàn)在很多了,傳統(tǒng)的使用handler,高大上的就是用rxJava等異步操作庫。 -
Binder線程:
Binder線程可能很多人用的不多,它是用于不同的進程之間的通信,其實每一個進程都會有一個線程池來用出來別的進程發(fā)送過來的消息,比如:系統(tǒng)服務,Intents,ContentProviders,Service等,典型的用例就是應用使用Binder線程提供一個service給其他進程通過AIDL接口進行綁定。 -
后臺線程:
這個你要是不知道什么意思就過分了,它其實就是我們一直說的子線程,創(chuàng)建出來內(nèi)容時空的,需要我們自己添加任務后start。不過其實要是上升到Linux層面主線程跟子線程是一樣的東西,只是Android框架里面添加了主線程跟后臺線程的概念,限制了后臺線程能力,確保UI是線程安全的。
HandlerThread
HandlerThread是一個自帶Looper跟MessageQueue的線程,也就是說這個線程是一個能夠?qū)崿F(xiàn)異步操作的子線程。而且它會一直等待消息進行處理。下面它的基本用法:
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper()){
@Override
public void handlerMessage(Message msg){
super.handlerMessage(msg);
//處理收到的消息
}
};
也是因為HandlerThread自帶Looper,所以HandlerThread里面的任務是按順序執(zhí)行的,吞吐量也會受到一定的影響,不會這個是我認為實現(xiàn)異步的比較好理解的一種方式了。
AsyncQueryHandler
AsyncQueryHandler主要用在ContnetProvider里面,用于執(zhí)行Create,Read,Update,delete操作的工具類,AsyncQueryHandler主要封裝了ContentResolver,HandlerThread,Handler等實現(xiàn)了對ContentProvider的異步操作,原理如圖所示:

(圖片不好找,自己照著畫了一個)
通常使用AsyncQueryHandler會跟著ContentProvider一起使用,AsyncQueryHandler封裝了如下四種方法來操作ContentProvider:
final void startDelete(...);
final void startInsert(...);
final void startQuery(...);
final void startUpdate(...);
相對的AsyncQueryHandler有相應的回調(diào)函數(shù),可以得到上面四個方法的返回結(jié)果:
@Override
protected void onDeleteComplete(...){...}
@Override
protected void onUpdateComplete(...){...}
@Override
protected void onInsertComplete(...){...}
@Override
protected void onQueryComplete(...){...}
IntentService
service我們熟悉的生命周期函數(shù)都是運行在主線程中的,本身并不是一個異步處理的技術。為了service里面可以使用子線程處理耗時任務,Android引入了IntentService,service的一個子類,具有跟service一樣的生命周期,同時也提供著后臺線程異步處理任務的機制,這一點跟上面講到的HandlerThread十分的相似,IntentService會后臺順序執(zhí)行所有任務,與我們遇到的一些后臺下載場景十分的契合。
我們可以使用一個Intent類型的參數(shù)啟動IntentService的異步執(zhí)行,如果IntentService已經(jīng)啟動了,新的Intent將會進入隊列進行等待,如果沒有運行將會啟動一個新的IntentService。當IntentService運行完所有的后臺任務后,會自動結(jié)束自己的生命周期,不需要開發(fā)者手動結(jié)束,這是我覺得比較好的地方。
IntentService本身是一個抽象類,因此繼承它需要實現(xiàn)它的抽象方法onHandleIntent來處理后臺的業(yè)務邏輯,同時需要在構(gòu)造方法中調(diào)用super(String name)傳入子類的名字,示例代碼如下:
public class SimpleIntentService extends IntentService{
public SimpleIntentService(){
super(SimpleIntentService.class.getName());
setIntentRedelivery(true);
}
@Override
protected void onHandleIntent(Intent intent){
//此處寫后臺邏輯
}
}
上面的setIntentRedelivery方法如果設置為true,那么IntentService的onStartCommand方法將會返回START_REDELIVER_INTENT。這時要是onHandleIntent調(diào)用之前進程死掉了,那么進程將會重新啟動,intent也會重新投遞。
使用IntentService最重要的一點就是,大家記得在AndroidManifest.xml文件里注冊聲明。
其實大家如果有興趣的話可以查看下IntentService的源碼,里面其實是通過HandlerThread來實現(xiàn)的,套了一層service的馬甲,源碼有點多,就貼幾句:
public abstract class IntentService extends Service {
...
private final class ServiceHandler extends Handler{
...
@Override
public void handleMessage(Message msg){
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
@Override
public void onCreate(){
...
HandlerThread thread = new HandlerThread("IntentService["++"mName"]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(Intent intent,int startId){
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
...
}
總結(jié)
本文先總結(jié)了Android里面三種異步處理的技術,這只是其一,后面還會總結(jié)書中提到的另外三種技術:Loader,AsyncTask,Executor Framework。如開頭提到的文中都是些看《Android高級進階》一本的知識點總結(jié),寫的都是自己比較淺顯的理解,書中有更詳細的篇幅介紹,感興趣的朋友可以找來看看,里面全是干貨。最后歡迎大家交流共同進步。