歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android Handler 主線程 子線程 雙向通信

Android Handler 主線程 子線程 雙向通信

日期:2017/3/1 10:16:56   编辑:Linux編程

Andriod提供了 Handler 和 Looper 來滿足線程間的通信。例如一個子線程從網絡上下載了一副圖片,當它下載完成後會發送消息給主線程,這個消息是通過綁定在主線程的Handler來傳遞的。

在Android,這裡的線程分為有消息循環的線程和沒有消息循環的線程,有消息循環的線程一般都會有一個Looper,這個事android的新 概念。我們的主線程(UI線程)就是一個消息循環的線程。針對這種消息循環的機制,我們引入一個新的機制Handle,我們有消息循環,就要往消息循環裡 面發送相應的消息,自定義消息一般都會有自己對應的處理,消息的發送和清除,消息的的處理,把這些都封裝在Handle裡面,注意Handle只是針對那 些有Looper的線程,不管是UI線程還是子線程,只要你有Looper,我就可以往你的消息隊列裡面添加東西,並做相應的處理。 但是這裡還有一點,就是只要是關於UI相關的東西,就不能放在子線程中,因為子線程是不能操作UI的,只能進行數據、系統等其他非UI的操作。

但是這裡還有一點,就是只要是關於UI相關的東西,就不能放在子線程中,因為子線程是不能操作UI的,只能進行數據、系統等其他非UI的操作。

一個Handler的創建它就會被綁定到這個線程的消息隊列中,如果是在主線程創建的,那就不需要寫代碼來創建消息隊列了,默認的消息隊列會在主線程被創建。但是如果是在子線程的話,就必須在創建Handler之前先初始化線程的消息隊列。如下面的代碼:

Java代碼
class ChildThread extends Thread {

public void run() {

/*
* 創建 handler前先初始化Looper.
*/
Looper.prepare();

/*
* 在子線程創建handler,所以會綁定到子線程的消息隊列中
*
*/
mChildHandler = new Handler() {

public void handleMessage(Message msg) {

/*
* Do some expensive operations there.
*/
}
};

/*
* 啟動該線程的消息隊列
*/
Looper.loop();
}
}


當Handler收到消息後,就會運行handleMessage(…)的回調函數,可以在裡面做一些耗時的操作。


最後完成了操作要結束子線程時,記得調用quit()來結束消息循環隊列。

mChildHandler.getLooper().quit();

下面是一個線程間通信的小例子:

public class omg extends Activity
{
private static final String TAG = "MainThread";
private Handler mMainHandler = null;
private TextView info = null;
private Button msgBtn = null;
private Button btn1 = null;
private int nClick = 0;
ChildThread child1 = null;
ChildThread child2 = null;

class ChildThread extends Thread {
private Handler childHander = null;
private int nClickTimes = 0;
private static final String CHILD_TAG = "ChildThread";

public void run() {
this.setName("ChildThread");

// 初始化消息循環隊列,需要在Handler創建之前
Looper.prepare();

childHander = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(CHILD_TAG,
"Got an incoming message from the main thread - "
+ (String) msg.obj);

try {

// 在子線程中可以做一些耗時的工作
String sMsg = "";
sleep(1000);

Message toMain = new Message();

// mMainHandler.obtainMessage();
sMsg = String.valueOf(++nClickTimes);
toMain.obj = sMsg + "This is "
+ this.getLooper().getThread().getName()
+ ". 你發送了消息: \"" + (String) msg.obj + "\"?"
+ "這是弟" + sMsg + "次 ";

mMainHandler.sendMessage(toMain);
Message toChild = new Message();
toChild.obj = "over";
// mChildHandler.sendMessage(toChild);

Log.i(CHILD_TAG, "Send a message to the main thread - "
+ (String) toMain.obj);

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

};

// 啟動子線程消息循環隊列
Looper.loop();

}
}

// //////////////////////////////////////////////////////////////////////////

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

info = (TextView) findViewById(R.id.info);
msgBtn = (Button) findViewById(R.id.msgBtn);
btn1 = (Button) findViewById(R.id.button1);

mMainHandler = new Handler() {

@Override
public void handleMessage(Message msg) {
Log.i(TAG, "Got an incoming message from the child thread - "
+ (String) msg.obj);

// 接收子線程的消息
info.setText((String) msg.obj + String.valueOf(nClick));
}

};

child1 = new ChildThread();
child1.start();

child2 = new ChildThread();
child2.start();

msgBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

if (child1.childHander != null) {

// 發送消息給子線程
Message childMsg = child1.childHander.obtainMessage();
Message msg = new Message();
msg.obj = mMainHandler.getLooper().getThread().getName()
+ " says Hello and msbBtn sending";

child1.childHander.sendMessage(msg);
Log.i(TAG, "Send a message to the child thread - "
+ (String) msg.obj);
}
}
});

btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (child2.childHander != null) {

// 發送消息給子線程
Message childMsg = child2.childHander.obtainMessage();
Message msg = new Message();
msg.obj = mMainHandler.getLooper().getThread().getName()
+ " says Hello and btn1 sending";
child2.childHander.sendMessage(msg);
Log.i(TAG, "Send a message to the child thread - "
+ (String) msg.obj);
}

}

});

}

public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Stop looping the child thread's message queue");

if (child1.childHander != null) {
child1.childHander.getLooper().quit();
}
if (child2.childHander != null) {
child2.childHander.getLooper().quit();
}

}
}

Copyright © Linux教程網 All Rights Reserved