常用的兩種handler呼叫方法
一、Handler、Thread、HandlerThread三者之間的關係如下:
1、Handler:在android中負責傳送和處理訊息,通過它可以實現其他支線執行緒與主執行緒之間的訊息通訊。
2、Thread:Java程序中執行運算的最小單位,亦即執行處理機排程的基本單位。某一程序中一路單獨執行的程式。
3、HandlerThread:一個繼承自Thread的類HandlerThread。
二、Handler跟Thread結合使用,首先在FirstHandler.java類中建立要在介面呼叫的getSum方法,具體實現如下:
package com.example.handlerdemo; import android.os.Handler; import android.os.Message; public class FirstHandler { private Handler mHandler; public static final int ADD_FLAG = 1; public void setHandler(Handler handler){ mHandler = handler; } public synchronized void getSum(final int a, final int b){ Logger.d("a = " + a + " ,b = " + b); class AddRunThread implements Runnable{ @Override public void run() { Logger.d("FirstHandler ThreadId = " + Thread.currentThread().getId()); int sum = add(a, b); try { Thread.sleep(6 * 1000); //模擬加法運算是一個非常複雜的運算,所以要開執行緒 } catch (InterruptedException e) { e.printStackTrace(); } String result = "result = " + sum; Message message = mHandler.obtainMessage(); message.what = ADD_FLAG; message.obj = result; mHandler.sendMessage(message); //在新的執行緒中進行傳送Message訊息 } } Thread addRun = new Thread(new AddRunThread()); addRun.setPriority(Thread.MAX_PRIORITY); //設定執行緒優先順序 addRun.start();//執行緒啟動 } /** * 實現加法運算 */ private int add(int a, int b){ return a + b; } }
當呼叫 getSum方法的時候會先啟動addRun執行緒,addRun執行緒啟動後就會執行AddRunThread類裡面的run方法,run方法裡面執行了一個加法運算的add方法,然後會執行Thread.sleep(6 * 1000)來模擬耗時的操作。加法運算add方法實行結束後會通過mHandler.sendMessage(message)來通知介面更新資訊。接下來看一下介面MainActivity的實現,具體如下:
package com.example.handlerdemo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.TextView; public class MainActivity extends Activity { private TextView textView; private FirstHandler firstHandler; private SecondHandler secondHandler; private String result; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { Logger.d("Handler ThreadId = " + Thread.currentThread().getId()); switch (msg.what) { case FirstHandler.ADD_FLAG: Logger.d("FirstHandler.ADD_FLAG"); textView.setText((String) msg.obj); //更新加法運算後的結果 break; case SecondHandler.UI_REFLESH: Logger.d("SecondHandler.UI_REFLESH"); textView.setText((String) msg.obj); //更新減法運算後的結果 break; default: break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Logger.d("main ThreadId = " + Thread.currentThread().getId()); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.tx_show); firstHandler = new FirstHandler(); secondHandler = new SecondHandler(); } /* * handler跟Thread結合使用的測試方法 */ public void addCheck(View view){ Logger.d(); firstHandler.setHandler(handler); //設定Handler物件例項 firstHandler.getSum(3000, 4600); //呼叫FirstHandler類的getSum方法 } /* * handler跟HandlerThread結合使用的測試方法 */ public void decreaseClick(View view){ Logger.d(); secondHandler.getSerialThread().post(new Runnable() { @Override public void run() { Logger.d("SecondHandler ThreadId = " + Thread.currentThread().getId()); int sum = decrease(300, 180); try { Thread.sleep(8 * 1000); //模擬減法運算是一個非常複雜的運算,所以要開執行緒 } catch (InterruptedException e) { e.printStackTrace(); } result = "result2 = " + sum; Message message = new Message(); message.what = SecondHandler.UI_REFLESH; message.obj = result; handler.sendMessage(message); //通過主執行緒更新UI } }); } //減法運算 private int decrease(int a, int b){ return a - b; } }
可以看到在handleMessage中進行了訊息處理,當msg.what等於FirstHandler.ADD_FLAG時,就會將加法運算的結果設定到textView中展示。
三、handler跟HandlerThread結合使用。程式碼邏輯主要在SecondHandler.java類中實現,具體如下:
package com.example.handlerdemo; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; public class SecondHandler { public Handler uiHandler = new Handler(Looper.getMainLooper()); //main主執行緒,由於更新UI更新 private HandlerThread mHandlerThread; private Handler handler; public static final int UI_REFLESH = 0X02; //設定handler物件關聯 public void setUIhandler(Handler handler){ uiHandler = handler; } /** *獲取獲得Looper物件的Handler例項 */ public synchronized Handler getSerialThread(){ if (null == mHandlerThread){ HandlerThread thread = new HandlerThread("work_thread");//工作執行緒,用於耗時的操作,不能用於更新UI thread.start(); handler = new Handler(thread.getLooper()){ }; } return handler; } }
通過 new Handler(thread.getLooper())來建立handler跟HandlerThread的聯絡。接下來看一下具體怎麼呼叫getSerialThread()方法,如下:
/*
* handler跟HandlerThread結合使用的測試方法
*/
public void decreaseClick(View view){
Logger.d();
secondHandler.getSerialThread().post(new Runnable() {
@Override
public void run() {
Logger.d("SecondHandler ThreadId = " + Thread.currentThread().getId());
int sum = decrease(300, 180);
try {
Thread.sleep(8 * 1000); //模擬減法運算是一個非常複雜的運算,所以要開執行緒
} catch (InterruptedException e) {
e.printStackTrace();
}
result = "result2 = " + sum;
Message message = new Message();
message.what = SecondHandler.UI_REFLESH;
message.obj = result;
handler.sendMessage(message); //通過主執行緒更新UI
}
});
}
//減法運算
private int decrease(int a, int b){
return a - b;
}
首先通過 getSerialThread()方法獲取secondHandler物件,然後呼叫了post方法,在run方法中執行了減法decrease(300, 180)運算,減法運算結束後會呼叫一個休眠函式Thread.sleep(8 * 1000),休眠8秒來模擬是耗時操作,休眠結束後會通過主執行緒的handler來通知介面更新減法的結果。執行結果如下: