編輯:關於Android編程
Thread thread = new Thread() { public void run() { //子線程中發送消息給主線程 Message msg = new Message(); msg.what = 200; msg.obj = param; msg.arg1 = 3; handler.sendMessage(msg); }; }; Handler handler = new Handler() { public void handleMessage(Message msg) { //主線程接收到消息,更新UI }; };
public Handler() { this(null, false); } public Handler(Callback callback, boolean async) { mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
final MessageQueue mQueue; //消息隊列(鏈表結構,下面會分析到) final Looper mLooper; //可理解為消息處理器而MessageQueue是Looper的成員屬性。
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) {} return enqueueMessage(queue, msg, uptimeMillis); } private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { //注意這一行,將Handler自已賦值給了Message的target屬性,下面的析中會用到 msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
boolean enqueueMessage(Message msg, long when) { synchronized (this) { msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { prev = p; p = p.next; if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; }
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }
Looper.prepare(); Looper.loop();這裡面大有學問,在繼續往下分析之前,我們再大膽猜測UI線程加載Activity的過程的前後也調用了這兩個方法。
public static void prepare() { prepare(true); } //設置當前線程私有的Looper對象 private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } //定義當前線程私有的Looper對象 static final ThreadLocalsThreadLocal = new ThreadLocal (); //獲取當前線程私有的Looper對象 public static Looper myLooper() { return sThreadLocal.get(); }
/** * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */ public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } msg.target.dispatchMessage(msg); msg.recycle(); } }
/** * Handle system messages here. */ public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
在多線程的環境中,主線程和子線程之間交互是通過一個鏈表結構的消息隊列(MessageQueue),子線程只管往裡面放入消息(Message),消息是按時間的先後順序排列的,主線程用一個消息處理器(Looper)不斷地逐個逐個地處理掉消息。
@容新華技術博客 - http://blog.csdn.net/rongxinhua - 原創文章,轉載請注明出處
1.返回棧Android 是使用任務(Task)來管理活動的,一個任務就是一組存放在棧裡的活動的集合,這個棧也被稱作返回棧(Back Stack)。棧是一種後進先出的數據
Android圖形庫Skia(四)-生成PDF 本文主要記錄使用skia庫生成pdf文件的過程,其實skia並不僅僅能在Android系統中使用,在一
在我們的項目開發過程中,經常會對用戶的信息進行分組,即通過組來顯示用戶的信息,同時通過一定的查詢條件來顯示查詢後的相關用戶信息,並且通過顏色選擇器來設置列表信息的背景顏色
本文均屬自己閱讀源碼的點滴總結,轉賬請注明出處謝謝。歡迎和大家交流。qq:1037701636 email: [email protected] 在前面的博文