1. 程式人生 > >Android面試-非同步訊息處理機制

Android面試-非同步訊息處理機制

【>>>Handler:{    什麼是handler、handler的使用方法、handler機制的原理、handler引起的記憶體洩漏以及解決辦法<非靜態內部類使用外部類的引用造成的。>    沒法在子執行緒建立Handler:需要一個訊息佇列來儲存它傳送的訊息,而預設子執行緒中是沒有開啟Looper輪詢器的,而訊息佇列又是通過Looper來管理的。在子執行緒中建立Handler是沒有關聯到MessageQueue,來讓你儲存訊息,會丟擲異常。如果想在子執行緒中建立一個Handler,你必須自己去初始化一個looper,然後在通過Looper.loop開啟一個迴圈,才能建立Handler。===什麼是handler:[    主執行緒也稱UI執行緒,不是執行緒安全的,是Android訊息機制的上層介面。    handler通過傳送和處理Message和Runnable物件來關聯相對應執行緒的MessageQueue。    1、可以讓對應的Message和Runnable在未來的某個時間點進行相應處理。    2、讓自己想要處理的耗時操作放在子執行緒,讓更新ui的操作放在主執行緒。]===handler的使用:[    1、post(runnable):底層呼叫的還是sendMessage,進行了一層封裝。--->post(runnable):    private Handler uihandler = new Handler();    uihandler.post(runnable);    2、sendMessage(message)--->sendMessage例項:    private Handler uiHandler = new Handler(){           private void handMessage(Message msg){                switch(msg.what){ case 1: ...... break; }            }    }    Message msg = new Message();    msg.what = 1;    uihandler.sendMessage(msg);]===handler機制的原理:[---Looper:有一個mQueue訊息佇列,Android每個執行緒有單獨唯一的Looper。loop()方法建立一個死迴圈,通過prepare()建立Looper。---MessageQueue:有一個mMessage訊息---Message:有一個Handler物件---Handler:有mQueue和mLooper物件。一定要在主執行緒而不能在內部類中建立Handler。作用是接收發送訊息,還有就是處理訊息。1、Looper取出對頭Message2、對應的Handler執行handleMessage3、返回Looper繼續執行]===handler引起的記憶體洩漏以及解決辦法:[     Activity有Handler例項的引用,Handler在做耗時操作一直存在,Activity沒法銷燬。    A、原因:非靜態內部類持有外部類的匿名引用,導致外部activity無法釋放。    B、解決辦法:handler內部持有外部activity的弱引用,並把handler改為靜態內部類,mHandler.removeCallback()。]}>>>Asynctask
:{    什麼是AsyncTask、AsyncTask的使用方法、AsyncTask內部原理、AsyncTask的注意事項===什麼是Asynctask:[    是Android提供的輕量級的非同步類,是一個抽象類。它本質上就是一個封裝了執行緒池和handler的非同步框架。需要注意的是它只能做一些耗時比較短的操作。]===Asynctask的使用方法:[1、三個引數:extends<引數1,引數2,引數3>    引數1:傳入的引數    引數2:需要在介面上顯示當前的進度    引數3:結果返回引數型別5、5個方法    onPreExecute():UI執行緒中呼叫的,未開始之前做初始化操作。    doInBackground(...):在子執行緒中執行,做一些較短時間的耗時操作。傳遞給onPostExecute。publishProgress(i);    onProgressUpdate(...):進度更新    onPostExecute(...):操作結束。接收doInBackground返回的值。    構造方法:]===Asynctask機制原理:[1、AsyncTask的本質是一個靜態的執行緒池,AsyncTask派生出的子類可以實現不同的非同步任務,這些任務都是提交到靜態的執行緒池中執行。2、執行緒池中的工作執行緒執行doInBackground(mParams)方法非同步任務3、當任務狀態改變之後,工作執行緒會向UI執行緒傳送訊息,SayncTask內部的IntentnalHandler相應這些訊息,並呼叫相應的回撥函式。]===AsyncTask注意事項:[1、記憶體洩漏    宣告為非靜態內部類,會持有外部類的匿名引用,外部類無法被回收。    A、可以把AsyncTask設定成靜態的    B、在AsyncTask中持有Activity的弱引用    C、onDestroy()進行AsyncTesk的finish操作cancel
方法呼叫。2、生命週期    生命週期不會依附於Actiivty的生命週期,要主動呼叫cancel方法,可在Activity關閉前導致崩潰:子執行緒在執行,更新UI而介面不存在。3、結果丟失    螢幕旋轉或Activity退到後臺、記憶體不夠被殺掉,而Activity重新被建立,原來的見面失效,去更新介面就不會生效。4、並行or序列    1.6之前都是序列,有序執行;1.6到2.3改成並行;在2.3之後為維護系統的穩定,又改成了序列,但是還是可以執行並行<執行緒池執行方式>,如果採用併發,系統執行緒是不穩定的。]}>>>handlerThread:{    handlerThread是什麼、handlerThread原始碼解析===handlerThread產生背景:[    開啟Thread子執行緒進行耗時操作,多次建立和銷燬執行緒是很消耗系統資源的,影響效能。採用迴圈執行緒,使其執行多個耗時任務。handler+thread+looper      是一個thread內部有looper]===handlerThread的特點:[    HandlerThread本質上是一個執行緒類,它繼承了Thread;    HandlerThread有自己的內部Looper物件,可以進行looper迴圈;    通過獲取HandlerThread的looper物件傳遞給Handler物件,可以在handlerMessage方法中進行非同步任務。    有點是不會有阻塞,減少了對效能的消耗,缺點是不能同時進行多工的處理,需要等待進行處理。處理效率低。    與執行緒池注重併發不同,HandlerThread是一個序列佇列,HandlerThread背後只有一個執行緒。]===handlerThread原始碼解析:[]}>>>intentservice
:{    intentservice是什麼、intentservice的使用方法、intentservice原始碼解析    繼承Service,但優先順序比Service高。內部封裝了Handler和HandlerThread===intentService是什麼:[    IntentService是繼承並處理非同步請求的一個類,在IntentService內有一個工作執行緒來處理耗時操作,啟動IntentService的方式和啟動傳統的Service一樣,同時,當任務執行完後,IntentService會自動停止,而不需要我們手動去控制或stopSelf()。另外,可以啟動IntentService多次,而每一個耗時操作會以工作佇列的方式在IntentService的onHandleIntent回撥方法中執行,並且,每次會執行一個工作執行緒,執行完第一個再執行第二個。    它本質是一種特殊的Service,繼承自Service並且本身就是一個抽象類。    它內部通過HandlerThread和Handler實現非同步操作。]===intentService的使用:[    繼承IntentService    /**    實現非同步任務的方法    Activity傳遞過來的Intent,資料封裝在intent中    */protected void onBandleIntent(Intent intent){ //Message實現訊息傳遞 }    A、建立IntentService是時,只需實現onHandleIntent和構造方法,onHandleIntent為非同步方法,可以執行耗時操作。]===intentservice原始碼解析:[public abstract class IntentService extends Service {//構造方法public IntentService(String name) {//回撥方法protected abstract void onHandleIntent(@Nullable Intent intent);---onCreate():會建立一個HandlerThread         mServiceLooper = thread.getLooper();        mServiceHandler = new ServiceHandler(mServiceLooper);   擁有執行非同步執行緒的Looper,就可以執行非同步任務。---onHandleIntent(@Nullable Intent intent):抽象方法,是一個非同步方法--- stopSelf(msg.arg1);  //有引數的情況,時候等到所有訊息傳遞後銷燬    它本質上就是一個封裝了HandlerThread和handler的非同步框架。]}】