Monday, January 14, 2013

[Android] 多執行緒-Handler和Thread的關係

要寫Android,難懂的多執行緒一定要給他搞懂
在Android當中,如果做超過5秒被系統強制關閉
收到Application not Responsed簡稱ANR
onCreate()如果做超過10秒就會跳ANR
所以繁重的事情不能在onCreate()裡頭做


有沒有解決辦法
Thread中文叫執行緒


搞不清楚
用現實的例子說明好了

Thread ==>  做工的工人
Runnable ==> 要做的工作事項 (工作說明書)

一般的Thread,工人請他來,指定工作給他做。做完就收工閃人回家
有一種Thread,他的性質比較不一樣
算是包月的那種特約駐點工人吧,要簽合約的(笑)
上班時間跟公務員一樣,就算沒事情做也要standby在那裡
這種工人他會有個經紀人幫他管要給他作的事
HandlerThread ==>  特約工人
Handler ==>  特約工人的經紀人
回到程式,一般來說,Activity 執行的時候
會有個 UI Thread 或叫 main Thread
就是你程式本身原有的執行緒,管著畫面呈現.....等等事物
main Thread (或叫UI Thread)就是你的程式進入點
而main Thread,他也是個HandlerThread
可以給他一個Handler,做接收訊息之用
以下程式碼只是示意,要表達程式碼的邏輯概念
實際上在運行的時候,模擬器的畫面不會產生任何的變化
可以把它當範本使用,稍加修改

package com.example.thread_project;




import android.os.Bundle;

import android.os.Handler;

import android.os.HandlerThread;

import android.app.Activity;

import android.view.Menu;



public class Main extends Activity {



// 找到UI工人的經紀人,這樣才能派遣工作(找到顯示畫面UI Thread的Handler)

private Handler mUI_Handler = new Handler();

// 宣告特約工人的經紀人

private Handler mThreadHandler;

// 宣告特約工人

private HandlerThread mThread;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);



// 聘請一個特約工人,有其經紀人派遣其工人做事(另起一個有Handler的Thread)

mThread = new HandlerThread("name");

// 讓Worker待命,等待其工作(開啟Thread)

mThread.start();

// 找到特約工人的經紀人,這樣才能派遣工作(找到Thread的Handler)

mThreadHandler = new Handler(mThread.getLooper());



// 請經紀人指派工作名稱r1,給工人做

mThreadHandler.post(r1);



}



private Runnable r1 = new Runnable() {



@Override

public void run() {

// TODO Auto-generated method stub



// ..............................

// 做了很多事

// 請經紀人指派工作名稱r1,給工人做



mUI_Handler.post(r2);



}



};



private Runnable r2 = new Runnable() {

public void run() {

// TODO Auto-generated method stub



// ..............................

// 顯示畫面的動作

}

};



protected void onDestroy() {

super.onDestroy();



// 移除工人上的工作

if (mThreadHandler != null) {

mThreadHandler.removeCallbacks(r1);

}



// 解聘工人(關閉Thread)

if (mThread != null) {

mThread.quit();

}

}



@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.activity_main, menu);

return true;

}















No comments:

Post a Comment