您好,登錄后才能下訂單哦!
這篇文章主要介紹Android中Handler、Thread、HandlerThread的區別有哪些,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
(1)Handler類,上官方文檔,Handler
public class Handler.A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
(2)Thread類,上官方文檔,Thread
public class Thread. extends Object implements Runnable.A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon. When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.
(3)HandlerThread類,上官方文檔,HandlerThread
public class HandlerThread. extends Thread. Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
①Handler:在android中負責發送和處理消息,通過它可以實現其他支線線程與主線程之間的消息通訊。
②Thread:Java進程中執行運算的最小單位,亦即執行處理機調度的基本單位。某一進程中一路單獨運行的程序。
③HandlerThread:一個繼承自Thread的類HandlerThread,Android中沒有對Java中的Thread進行任何封裝,而是提供了一個繼承自Thread的類HandlerThread類,這個類對Java的Thread做了很多便利的封裝。
———————————————————我是分割線—————————————————————
其實這個問題,最主要的關注點還是落在了HandlerThread類上,那么這個類到底有什么作用,所謂的便利封裝又體現在哪里?
觀察HandlerThread的官方文檔的兩句:①Thread. Handy class for starting a new thread that has a looper.②The looper can then be used to create handler classes.
釋義:HandlerThread對象start后可以獲得其Looper對象,并且使用這個Looper對象實例Handler,之后Handler就可以運行在其他線程中了。
———————————————————我是分割線—————————————————————
那么Handler和Looper到底是什么關系,為什么HandlerThread要做這樣的處理?觀看下圖:
Andriod提供了 Handler 和 Looper 來滿足線程間的通信。 Handler 先進先出原則。 Looper 類用來管理特定線程內對象之間的消息交換 (MessageExchange) 。
1)Looper: 一個線程可以產生一個 Looper 對象,由它來管理此線程里的 MessageQueue( 消息隊列 ) 和對消息進行循環。
2)Handler: 你可以構造 Handler 對象來與 Looper 溝通,以便 push 新消息到 MessageQueue 里 ; 或者接收 Looper 從 Message Queue 取出 所送來的消息。
3) Message Queue( 消息隊列 ): 用來存放線程放入的消息。
4) Message:是線程間通訊的消息載體。兩個碼頭之間運輸貨物,Message充當集裝箱的功能,里面可以存放任何你想傳遞的消息。
看到這里就明白了為什么:如果一個線程要處理消息,那么它必須擁有自己的Looper,并不是Handler在哪里創建,就可以在哪里處理消息。
注:對應關系Thread(1):Looper(1):MessageQueen(1):Handler(n).
正如前面所說,線程間通信的時候,比如Android中常見的更新UI,涉及到的是子線程和主線程之間的通信,實現方式就是Handler+Looper,但是要自己手動操作Looper,不推薦,所以谷歌封裝了HandlerThread類(類似于AsyncTask類)。
上代碼,具體實現:
public class MainActivity extends AppCompatActivity { Handler mainHandler,workHandler; HandlerThread mHandlerThread; TextView text; Button button1,button2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView) findViewById(R.id.text1); // 創建與主線程關聯的Handler mainHandler = new Handler(); /** * 步驟①:創建HandlerThread實例對象 * 傳入參數 = 線程名字,作用 = 標記該線程 */ mHandlerThread = new HandlerThread("handlerThread"); /** * 步驟②:啟動線程 */ mHandlerThread.start(); /** * 步驟③:創建工作線程Handler & 復寫handleMessage() * 作用:關聯HandlerThread的Looper對象、實現消息處理操作 & 與其他線程進行通信 * 注:消息處理操作(HandlerMessage())的執行線程 = mHandlerThread所創建的工作線程中執行 */ workHandler = new Handler(mHandlerThread.getLooper()){ @Override public void handleMessage(Message msg) { //設置了兩種消息處理操作,通過msg來進行識別 switch(msg.what){ case 1: try { //延時操作 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 通過主線程Handler.post方法進行在主線程的UI更新操作 mainHandler.post(new Runnable() { @Override public void run () { text.setText("第一次執行"); } }); break; case 2: try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } mainHandler.post(new Runnable() { @Override public void run () { text.setText("第二次執行"); } }); break; default: break; } } }; /** * 步驟④:使用工作線程Handler向工作線程的消息隊列發送消息 * 在工作線程中,當消息循環時取出對應消息 & 在工作線程執行相關操作 */ button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Message msg = Message.obtain(); msg.what = 1; //消息的標識 msg.obj = "A"; // 消息的存放 // 通過Handler發送消息到其綁定的消息隊列 workHandler.sendMessage(msg); } }); button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Message msg = Message.obtain(); msg.what = 2; msg.obj = "B"; workHandler.sendMessage(msg); } }); } @Override protected void onDestroy() { super.onDestroy(); mHandlerThread.quit(); // 退出消息循環 workHandler.removeCallbacks(null); // 防止Handler內存泄露 清空消息隊列 } }
從上面代碼可以看出,HandlerThread繼承于Thread,所以它本質就是個Thread。與普通Thread的差別就在于,然后在內部直接實現了Looper的實現,這是Handler消息機制必不可少的。有了自己的looper,可以讓我們在自己的線程中分發和處理消息。如果不用HandlerThread的話,需要手動去調用Looper.prepare()和Looper.loop()這些方法。
// 子線程中創建新的Handler 沒有使用HandlerThread new Thread () { @Override public void run() { Looper.prepare(); Hnadler handler = new Handler(); Looper.loop(); } }
提供一些其他Android消息機制分析,幫助理解讀者理解:
①Handler是Android消息機制的上層接口,通過它可以輕松地將一個任務切換到Handler所在的線程中去執行,該線程既可以是主線程,也可以是子線程,要看構造Handler時使用的構造方法中傳入的Looper位于哪里;
②Handler的運行需要底層的MessageQueue和Looper的支撐,Handler創建的時候會采用當前線程的Looper來構造消息循環系統,而線程默認是沒有Looper的,如果需要使用Handler就必須為線程創建Looper;
③上述代碼中的第一個Handler-mainHandler,實例化的時候,直接在onCreate()方法中new出了實例,其實是其已經在主線程中了,主線程-ActivityThread,ActivityThread被創建時就會初始化Looper,這就是主線程中默認可以直接使用Handler的原因;
④上述代碼中的第二個Handler-workHandler,它在實例化的時候,參數傳入了 mHandlerThread.getLooper() ,注意,這個Handler使用的就不是主線程的Looper了,而是子線程的Looper,HandlerThread在調用start()方法之后,就可以獲取到子線程的Looper,然后將其傳入workHandler的構造方法中,那么此時的workHandler就會運行在子線程中,用于處理耗時操作。
⑤Handler的工作原理:Handler創建時會采用當前線程的Looper來構建內部消息循環系統,如果當前線程沒有Looper,那么就會報錯“Can`t create handler inside thread that has not called Looper.prepare()”解決方法有兩個:為當前線程創建Looper即可,像上述代碼中workHandler,或者在一個有Looper的線程中創建Handler也行,就像上述代碼中的mainHandler一樣;
⑥調用Handler的post方法會將一個Runnable投遞到Handler內部的Looper中去處理,也可以通過Handler的send方法來發送一個消息,這個消息同樣會在Looper中去處理。其實post方法最終也是通過send方法來完成的。每當Looper發現有新消息到來時,就會處理這個消息,最終消息中的Runnable的run方法或者Handler的handleMessage方法就會被調用。注意Looper是運行在創建Handler所在的線程中的,這樣一來Handler中的業務邏輯就被切換到創建Handler所在的線程中去執行了;
⑦Looper的工作原理:Looper在Android的消息機制中扮演著消息循環的角色,具體來說就是它會不停地從MessageQueue中查看是否有新消息,如果有新消息就會立刻處理,否則就一直阻塞在那里。注意關注一些重要的Looper的方法:
Looper.prepare()-為當前線程創建一個Looper;
Looper.loop()-開啟消息循環,只有調用該方法,消息循環系統才會開始循環;
Looper.prepareMainLooper()-為主線程也就是ActivityThread創建Looper使用;
Looper.getMainLooper()-通過該方法可以在任意地方獲取到主線程的Looper;
Looper.quit() Looper.quitSafely()-退出Looper,自主創建的Looper建議在不使用的時候退出
⑧ActivityThread主線程通過ApplicationThread和AMS進行進程間通信
以上是“Android中Handler、Thread、HandlerThread的區別有哪些”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。