5 Handler与子线程
5-1?自定義與線程相關的Handler?
1.在線程中通過Looper.prepare()方法創建一個與線程相關的Looper對象;
2.?在線程中通過Handler的new關鍵字,創建一個Handler對象,這個對象在創建的時候會關聯上1中創建的Looper對象
3.?調用Looper對象的loop()方法去輪詢它的MessageQueue
4.?通過其他的線程拿到這個線程的Handler對象之后調用sendMessage()之后,在這個線程中就可以進行Message的處理了。
我們一般是在主線程中創建Handler對象,在主線程中處理Message,在子線程中調用這個Handler對象的sendMessage()來發送message。所以Handler是在哪個線程創建就有哪個線程處理Message和輪詢,而由別的線程負責給這個Handler發送Message。
1.注意:在主線程中創建的Handler的handleMessage()方法不要寫耗時的操作,否則會導致UI卡死,因為這個handleMessage()方法是在UI線程中調用的。
package com.example.yzx; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.widget.TextView;public class SecondActivity extends Activity {private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {System.out.println("UI---------" + Thread.currentThread());};};class MyThread extends Thread {public Handler handler;@Overridepublic void run() {// TODO Auto-generated method stub Looper.prepare();handler = new Handler() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubSystem.out.println("currentThead:" + Thread.currentThread());}};Looper.loop();}}private MyThread thread;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);TextView textView = new TextView(this);textView.setText("hellow Handler");setContentView(textView);thread = new MyThread();thread.start();try {Thread.sleep(500);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}thread.handler.sendEmptyMessage(1);handler.sendEmptyMessage(1);} }?
5-2?HanlderThread是什么?(11:51)
HandlerThread避免多線程導致空指針問題。
handlerthread?默認【創建一個looper然后和一handler關聯,那么所有的handleMessage方法是在一個子線程中進行,可以用handlerthread模擬一個異步任務,將主線程的任務發送個子線程,處理一些比較耗時操作
-----------------------------------------------------------------------------------------
1.一個Handler的創建它就會被綁定到這個線程的消息隊列中,如果是在主線程創建的,那就不需要寫代碼來創建消息隊列了,默認的消息隊列會在主線程被創建。但是如果是在子線程的話,就必須在創建Handler之前先初始化線程的消息隊列
2.HandlerThread繼承于Thread,所以它本質就是個Thread。與普通Thread的差別就在于,它有個Looper成員變量。這個Looper其實就是對消息隊列以及隊列處理邏輯的封裝,簡單說就是?消息隊列+消息循環。
在其run()方法中,調用Looper.myLooper()獲得一個looper對象。
synchronized?(this)?{
mLooper?=?Looper.myLooper();
notifyAll();
在創建handler時使用getLooper()方法,其實現其實是一直等待looper對象的獲得。
while?(isAlive()?&&?mLooper?==?null)?{
try?{
wait();
}
}
3.Handler在創建的時候可以指定Looper,這樣通過Handler的sendMessage()方法發送出去的消息就會添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情況下,Handler綁定的是創建它的線程的Looper。如果這個線程的Looper不存在,程序將拋出"Can't?create?handler?inside?thread?that?has?not?called?Looper.prepare()"。
這個時候我們就需要使用HandlerThread這個類來創建這個Looper了,這樣消息的處理就在新創建的HandlerThread中進行。(如圖)
mThread?=?new?HandlerThread("Handler?Thread");
mHandler?=?new?Handler(mThread.getLooper()){
public?void?handleMessage(android.os.Message?msg)?{
...?};
};
兩個線程切換的過程中,looper沒有創建?會拋出控制異常
handlerThread用來避免這個異常
轉載于:https://www.cnblogs.com/crazyzx/articles/5477398.html
總結
以上是生活随笔為你收集整理的5 Handler与子线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javaScript初学笔记(二)
- 下一篇: iOS中NSLog输出格式大全