文章轉載只能用於非商業性質,且不能帶有虛擬貨幣、積分、註冊等附加條件。轉載須註明出處:http://blog.csdn.net/flowingflying/android
對於時間較長處理通常不放在UI線程(即主線程)中,避免出現ANR的現象,咱們會另啓一個線程,利用handler進行子線程和主線程之間的通訊,實現子線程觸發UI操做。這種類型的子線程一般稱爲worker thread。具體實現步驟以下:編程
一、在主線程建立Handler對象;ide
二、建立一個線程(即worker線程),將Handler對象傳遞給該線程;函數
三、運行線程,若是須要進行UI的操做,經過handler將message加入到主線程的隊列中。message實際成爲worker線程和主線程的通訊橋樑;學習
四、主線程處理message。this
小例子很簡單,如圖。點擊菜單,觸發處理(一、UI提示開始,二、sleep 10秒,三、UI提示結束),因爲處理時間很長,爲了不ANR的狀況,該處理將在線程中運行。.net
根據對象編程從上之下的設計思想,咱們看看主線程中如何啓動子線程,並將handler的對象傳遞到線程中。後面在補上相關的Handler集成和子線程的執行Runnable的實現。線程
public class MainActivity extends Activity {
... ...
@Override //點擊菜單觸發子線程
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if( id == R.id.menu_worker_thread){
testWorkerThread();
return true;
}
return super.onOptionsItemSelected(item);
}
private Handler reportHandler = null;
private Thread workerThread = null;
private void testWorkerThread(){
//【1】在主線程建立Handler對象
if(reportHandler == null){
reportHandler = new ReportStatusHandler(this);
}
//將handler傳遞至建立的線程,並開啓線程
if(workerThread!= null && workerThread.getState() != Thread.State.TERMINATED){
showinfo("Thread is new or alive, but not terminated"); //在Logcat和textview中顯示信息
}else{
showinfo("Old thread existed and terminated, create an new one");
workerThread = new Thread( new WorkerThreadRunnable(reportHandler) );
workerThread.start();
}
}
... ...
}設計
ReportStatusHandler集成Handler,根據message的內容進行相應的UI處理,和以前的學習沒有什麼差異。
public class ReportStatusHandler extends Handler{
private MainActivity parentActivity = null;
public static final String DATA_MESSAGE="cn.flowingflying.proandroid.testhandler.message";
public ReportStatusHandler(MainActivity activity){
parentActivity = activity;
}
@Override //【4】根據message的內容進行相應的UI處理,UI處理將在UI線程,即主線程中進行,所以ReportStatusHandler對象也應在主線程中建立。
public void handleMessage(Message msg) {
Bundle b = msg.getData();
String s = b.getString(DATA_MESSAGE);
// 在此進行UI操做,包括textview的和Toast的處理
…… UI處理
}
}
/* Runnable這是java中對線程執行內容的具體實現 */
public class WorkerThreadRunnable implements Runnable{
Handler handler = null; //記錄在主線程建立的handler參考
//【2】在構建函數中將主線程的handler傳遞過來
public WorkerThreadRunnable(Handler h){
handler = h;
}
@Override //子線程的執行內容,本例用sleep來進行模擬,在sleep的開始和結束子線程須要與UI線程互動,實際上咱們還能夠每sleep一秒就觸發一次互動。
public void run() {
informUi("WorkerThread is start running...");
for(int i = 0; i < 10; i ++){
try{
Thread.sleep(1000);
… … // Tell Ui thread to do something here ,for example informUi(…….);
}catch(Exception e){
Log.e("WorkerThreadRunnable",e.toString());
}
}
informUi("WorkerThread is finished...");
}
//【3】經過handler消息將message放入主線程的隊列,實現子線程和主線程的通訊
private void informUi(String s){
Message msg = handler.obtainMessage();
Bundle b = new Bundle();
b.putString(ReportStatusHandler.DATA_MESSAGE, s);
msg.setData(b);
handler.sendMessage(msg);
}
}
相關小例子源代碼可在Pro Android學習:瞭解Handler小例子中下載。
相關連接: 個人Android開發相關文章