Android 使用handler實現線程間發送訊息 (主線程 與 子線程之間)、(子線程 與 子線程之間)
關鍵字:Android 使用handler實現線程間發送訊息 (主線程 與 子線程之間)、(子線程 與 子線程之間)
相信大家平時都有使用到非同步線程往主線程(UI線程)發送訊息的情況。本文主要研究Handler的訊息發送。包括主線程往子線程發送訊息,子線程之間互相發送訊息。
一、主線程向子線程發送訊息。
實現過程比較簡單:
主線程發送訊息到非同步線程,非同步線程接收到訊息後在再發送一條訊息給主線程。
1. 初始化主線程的Handler,用來接收子線程的訊息。
2. 啟動非同步線程,在非同步線程中建立Looper,並初始化一個非同步線程的Handler。
3. 主線程擷取非同步線程的Handler(這裡涉及到線程間同步的知識),並向非同步線程發送訊息。
4. 非同步線程Handler接收到訊息以後,擷取主線程的Handler,並向主線程發送訊息。
5. 主線程收到非同步線程發來的訊息。
註:
1. 這裡說的主線程Handler或者非同步線程Handler,指的是綁定在對應線程訊息佇列上的一個Handler對象而已,在Handler的建構函式中傳入對應線程的Looper對象即可。
2. 為什麼要使用線程鎖來處理,是因為非同步線程啟動不是即時的,主線程擷取非同步線程的Handler時有可能為空白,如果為空白,需要等待非同步線程先初始化Handler。
上代碼:
package com.example.chen.myapplication;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;/** * 用Handler測試主線程往子線程發送訊息 * @author chen */public class HandlerSimpleActivity extends Activity { private Handler mainHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 啟動非同步線程 final AsyncThread asyncThread = new AsyncThread(); asyncThread.start(); // 初始化主線程的Handler mainHandler = new Handler(Looper.myLooper(), new Handler.Callback() { @Override public boolean handleMessage(Message msg) { // 主線程收到訊息 Log.e(HandlerSimpleActivity.class.getSimpleName(), MainHandler Receiver Message curThread = + Thread.currentThread().getName()); return false; } }); // 擷取非同步線程的Handler Handler handler = asyncThread.getHandler(); if (handler != null) { Log.e(HandlerSimpleActivity.class.getSimpleName(), MainThread Send Message curThread = + Thread.currentThread().getName()); // 向非同步線程發送訊息 handler.sendEmptyMessage(0); } } /** * 非同步線程 */ private class AsyncThread extends Thread { private Handler handler; @Override public void run() { super.run(); Log.e(HandlerSimpleActivity.class.getSimpleName(), AsyncThread Start curThread = + Thread.currentThread().getName()); Looper.prepare(); // 初始化非同步線程的訊息迴圈隊列 if (handler == null) { synchronized (AsyncThread.class) { // 線程間安全 // 為非同步線程的訊息迴圈隊列新增一個Handler handler = new Handler(Looper.myLooper(), new Handler.Callback() { @Override public boolean handleMessage(Message msg) { // 非同步線程收到訊息 Log.e(HandlerSimpleActivity.class.getSimpleName(), AsyncHandler Receiver Message curThread = + Thread.currentThread().getName()); // 非同步線程發送訊息到主線程 Log.e(HandlerSimpleActivity.class.getSimpleName(), AsyncThread Send Message curThread = + Thread.currentThread().getName()); mainHandler.sendEmptyMessage(0); return false; } }); // 非同步線程Handler初始化完畢 Log.e(HandlerSimpleActivity.class.getSimpleName(), AsyncHandler Inited curThread = + Thread.currentThread().getName()); // 釋放鎖 AsyncThread.class.notifyAll(); } } Looper.loop(); } /** * 擷取非同步線程的Handler * @return */ public Handler getHandler() { if (handler == null) { synchronized (AsyncThread.class) { // 線程間安全 if (handler == null) { try { // 擷取非同步線程的handler為空白,釋放鎖,等待非同步線程初始化完畢。 Log.e(HandlerSimpleActivity.class.getSimpleName(), getHandler wait curThread = + Thread.currentThread().getName()); AsyncThread.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } // 非同步線程Handler初始化完畢,主線程繼續 Log.e(HandlerSimpleActivity.class.getSimpleName(), getHandler notified curThread = + Thread.currentThread().getName()); return handler; } else { return handler; } } } else { return handler; } } }}
上結果:
二、子線程間使用Handler互相發送訊息:
2015年7月26日19:47:31 等待下次更新(*^__^*) 嘻嘻……