標籤:XML mat ui控制項 資料隔離 安全執行緒 lin hand 客戶 非同步處理
android的訊息機制——Handler:Handler是一個Android SDK 提供給開發人員方便進行非同步訊息處理的類。
一.為什麼用handler
1.訊息機制:不同線程之間的通訊。那麼推出來android的訊息機制可以用handler機制來概況.
2.那麼android為什麼會用到handler機制:避免ANR.
3.避免ANR的方法就是:子線程執行耗時操作,通過handler機制完成UI在主線程的更新.
4.那麼為什麼子線程不能執行UI:因為UI控制項不是安全執行緒的,那麼多線並發對UI進行操作會達到不可預期的結果.
5.那麼UI控制項為什麼不設計為安全執行緒的:因為設計為安全執行緒的,首先UI效能低效,其次有種殺雞焉用牛刀的感覺,UI設計是秉承著簡單有效原則,那麼有悖於設計.
二,handler中幾個關鍵的類(Handler、Looper、MessageQueue、Message、ThreadLocal):
1.從使用角度來說用handler就是:建立handler重寫handlermsg方法對訊息進行處理,通過線程sendmsg.
2.Handler特性:
a.Android裡沒有全域Message Queue訊息佇列,每個Activity都有一個獨立的訊息佇列且採用先進先出的原則.不同APK不能通過handle進行訊息傳遞.
b.每個handler執行個體都會綁定到建立它的線程中.
c.handler發送訊息到Message Queue中,每個massage發送到訊息佇列中採用先進先出原則.發送訊息採用非同步方式不會阻塞線程,而接受訊息採用同步方式會阻塞線程,即handler處理完一個mesage訊息對象後才會接著去取
下一個訊息進行處理.
3.那麼對於幾個經常用的類作用如下:
Handler負責發送和處理訊息
Looper訊息泵,將迴圈取訊息將取到的訊息交給handler進行處理.沒有訊息的時候將會處於阻塞狀態.
MessageQueue訊息佇列,負責存取訊息。
Message具體發送的訊息。
ThreadLocal它主要用於做線程間的資料隔離用的,這裡它在每個線程中存放各自對應的Looper。
三.常用handler訊息處理例子講解.
根據常用的幾種handler訊息傳遞使用方式進行講解.
首先建立一個activity,在activity執行個體3個button,分別處理常用的幾種類型的handler.
1.主線程建立handler自用.2.子線程通過Looper.getMainLooper()擷取父類的looper建立handler.3.將主線程的handler傳遞給子線程進行通訊.
public class MainActivity extends Activity implements OnClickListener{ Button mHandlerButton1 = null; Button mHandlerButton2 = null; Button mHandlerButton3 = null; Handler myHandler; Message msg; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main1); mHandlerButton1 = (Button)findViewById(R.id.handler_button1); mHandlerButton1.setOnClickListener(this); mHandlerButton2 = (Button)findViewById(R.id.handler_button2); mHandlerButton2.setOnClickListener(this); mHandlerButton3 = (Button)findViewById(R.id.handler_button3); mHandlerButton3.setOnClickListener(this); } public void onClick(View v){ if(v == mHandlerButton1){ myHandler = new MyHandler(); msg = myHandler.obtainMessage(1,"threadmain handler"); msg.sendToTarget(); }else if(v == mHandlerButton2){ InnerThread innerthread = new InnerThread(); innerthread.start(); }else if(v == mHandlerButton3){ myHandler = new MyHandler(); MyThread mythread = new MyThread(myHandler); mythread.start(); } } private class InnerThread extends Thread{ @Override public void run(){ //myHandler = new MyHandler();//僅能在主線程內採用不帶Looper對象建立Hanler對象.此處如果這麼用會拋異常 //myHandler = new MyHandler(Looper.myLooper());//Looper.myLooper擷取looper為null myHandler = new MyHandler(Looper.getMainLooper());//擷取父類的looper可以成功建立handler並發送訊息 msg = myHandler.obtainMessage(2,"InnerThread handler"); msg.sendToTarget(); } } private class MyThread extends Thread{ private Handler innerHandler; public MyThread(Handler handler){ this.innerHandler = handler;//通過構造器擷取主線程的handler並發送給主線程. } @Override public void run(){ msg = innerHandler.obtainMessage(3,"MyThread handler"); msg.sendToTarget(); } } public class MyHandler extends Handler{ public MyHandler(Looper myLooper){ super(myLooper); } public MyHandler(){}// @Override public void handleMessage(Message msg){ switch(msg.what){ case 1: Log.d("HandlerMessage","this handler is in main thread"); break; case 2: Log.d("HandlerMessage","this handler is in InnerThread"); break; case 3: Log.d("HandlerMessage","this handler is in MyThread"); break; default: break; } } }
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/handler_button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/handlerbutton1"/> <Button android:id ="@+id/handler_button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/handlerbutton2"/> <Button android:id ="@+id/handler_button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/handlerbutton3"/> </LinearLayout>
從handler特質來看,handler主要非同步處理較費時的操作,優先將介面返回給客戶,處理完成後進行ui的更新.
Android的訊息機制Handler