1) 先看一下最簡單的進度條示例
package com.sxz.android.thread;
import java.util.concurrent.atomic.AtomicBoolean;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
public class HandlerDemo extends Activity {
ProgressBar bar;
AtomicBoolean isRunning = new AtomicBoolean(false);
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
bar.incrementProgressBy(5);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_progressbar);
bar = (ProgressBar) findViewById(R.id.progressBar1);
}
@Override
protected void onStart() {
super.onStart();
Thread myThread = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 20 && isRunning.get(); i++) {
Message msg = mHandler.obtainMessage();
Thread.sleep(500);
msg.sendToTarget();
}
} catch (Throwable t)
{ }
}
});
isRunning.set(true);
myThread.start();
}
@Override
protected void onStop() {
super.onStop();
isRunning.set(false);
}
}
2) 基本概念
MessageQueue
消息隊列,存放消息的地方,按照FIFO規則執行,每一個線程只可以擁有一個MessageQueue,在創建 Looper 對象會創建一個MessageQueue對象。而每個 MessageQueue都會有一個對應的 Handler,Handler會向 MessageQueue通過兩種方法發送消息.
① sendMessage. 通過 sendMessage發送的是一個 message 對象,會被 Handler的 handleMessage() 函數處理。
② post 通過 post 方法發送的是一個 runnable 對象,則會自己執行。
這兩種消息都會插在 MessageQueue 隊尾並按先進先出的方式執行.但是通過這兩種方法發送出去的消息執行的方式略有不同.
③
④
Message
消息對象,MessageQueue中存放的對象。一個 MessageQueue中可以包含多個Message 對象。可以通過 Message.obtain() 或者 Handler.obtainMessage() 獲取 Message 對象.但是這並不一定是直接創建一個新的實例.而是先從消息池中看有沒有可用的 Message實例。存在則直接取出后返回這個實例。如果消息池中沒有可用的 Message 實例,則用給定的參數創建一個Message 對象。調用 removeMessage()時,將 Message 從 MessageQueue 中刪除,同時放入到消息池中。
消息,其實可以理解為線程間交流的信息,處理數據后台線程需要更新 UI,則發送Message內含一些數據給 UI線程.
Looper
操作 MessageQueue,一個 Looper 對應一個 MessageQueue.通過調用 Looper.myLooper() 可以獲取當前線程的 Looper對象.Looper 從 MessageQueue中取出 Message然后, 交由
Handler的 handleMessage() 進行處理。處理完成后,調用 Message.recycle()將其放入消息池中.
Looper 是每條線程里的 MessageQueue的管家。Android沒有 Gloabal 的 MessageQueue,而 Android 會自動替主線程(UI線程) 建立MessageQueue,但在子線程里並沒有建立MessageQueue。所以調用 Looper.getMainLooper() 得到的主線程Looper不為 NULL,但是調用Looper.myLooper()得到的Looper就有可能為 NULL。
Handler
消息的處理者。handler 負責將需要傳遞的信息封裝成 Message 對象,然后調用 sendMessage() 方法將消息放入 MessageQueue中,當MessageQueue循環到該 Message, 調用相應的
handler 對象的 handleMessage() 方法對其進行處理。Handler 都可以共享同一個 Looper 和 MessageQueue.
