在前文《Android多线程分析之二:Thread的实现》中已经详细分析了Android Thread 是如何创建,运行以及销毁的,其重点是对相应 native 方法进行分析,今天我将聚焦于 Android Framework 层多线程相关的类:Handler, Looper, MessageQueue, Message 以及它们与Thread 之间的关系。可以用一个不太妥当的比喻来形容它们之间的关联:如果把 Thread 比作生产车间,那么 Looper 就是放在这车间里的生产线,这条生产线源源不断地从 MessageQueue 中获取材料 Messsage,并分发处理 Message (由于Message 通常是完备的,所以 Looper 大多数情况下只是调度让 Message 的 Handler 去处理 Message)。正是因为消息需要在 Looper 中处理,而 Looper 又需运行在 Thread 中,所以不能随随便便在非 UI 线程中进行 UI 操作。 UI 操作通常会通过投递消息来实现,只有往正确的 Looper 投递消息才能得到处理,对于 UI 来说,这个 Looper 一定是运行在 UI 线程中。
在编写 app 的过程中,我们常常会这样来使用 Handler:
Handler mHandler = new Handler();
mHandler.post(new Runnable(){
@Override
public void run() {
// do somework
}
});或者如这系列文章第一篇中的示例那样: private Handler mHandler= new Handler(){
@Override
public void handleMessage(Message msg) {
Log.i("UI thread", " >> handleMessage()");
switch(msg.what){
case MSG_LOAD_SUCCESS:
Bitmap bitmap = (Bitmap) msg.obj;
mImageView.setImageBitmap(bitmap);
mProgressBar.setProgress(100);
mProgressBar.setMessage("Image downloading success!");
mProgressBar.dismiss();
break;
case MSG_LOAD_FAILURE:
mProgressBar.setMessage("Image downloading failure!");
mProgressBar.dismiss();
break;
}
}
};
Message msg = mHandler.obtainMessage(MSG_LOAD_FAILURE, null);
mHandler.sendMessage(msg); final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
final boolean mAsynchronous;
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
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;
}
public Handler() {
this(null, false);
}mLooper:线程的消息处理循环,注意:并非每一个线程都有消息处理循环,因此 Framework 中线程可以分为两种:有 Looper 的和无 Looper 的。为了方便 app 开发,Framework 提供了一个有 Looper 的 Thread 实现:HandlerThread。在前一篇《Thread的实现》中也提到了两种不同 Thread 的 run() 方法的区别。
/**
* Handy class for starting a new thread that has a looper. The looper can then be
* used to create handler classes. Note that start() must still be called.
*/
public class HandlerThread extends Thread {
Looper mLooper;
/**
* Call back method that can be explicitly overridden if needed to execute some
* setup before Looper loops.
*/
protected void onLooperPrepared() {
}
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
/**
* This method returns the Looper associated with this thread. If this thread not been started
* or for any reason is isAlive() returns false, this method will return null. If this thread
* has been started, this method will block until the looper has been initialized.
* @return The looper.
*/
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
}/** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
* this looper, before actually starting the loop. Be sure to call
* {@link #loop()} after calling this method, and end it by calling
* {@link #quit()}.
*/
public static void prepare() {
prepare(true);
}
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));
} /**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static Looper myLooper() {
return sThreadLocal.get();
}Handler 的成员变量 mQueue 是其成员变量 mLooper 的成员变量,这里只是为了简化书写,单独拿出来作为 Handler 的成员变量;成员变量 mCallback 提供了另一种使用Handler 的简便途径:只需实现回调接口 Callback,而无需子类化Handler,下面会讲到的:
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*/
public interface Callback {
public boolean handleMessage(Message msg);
}同是否有无 Looper 来区分 Thread 一样,Handler 的构造函数也分为自带 Looper 和外部 Looper 两大类:如果提供了 Looper,在消息会在该 Looper 中处理,否则消息就会在当前线程的 Looper 中处理,注意这里要确保当前线程一定有 Looper。所有的 UI thread 都是有 Looper 的,因为 view/widget 的实现中大量使用了消息,需要 UI thread 提供 Looper 来处理,可以参考view.java:
view.java
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
ViewRootImpl.java
private void performTraversals() {
....
// Execute enqueued actions on every traversal in case a detached view enqueued an action
getRunQueue().executeActions(attachInfo.mHandler);
...
}
static RunQueue getRunQueue() {
RunQueue rq = sRunQueues.get();
if (rq != null) {
return rq;
}
rq = new RunQueue();
sRunQueues.set(rq);
return rq;
}
/**
* The run queue is used to enqueue pending work from Views when no Handler is
* attached. The work is executed during the next call to performTraversals on
* the thread.
* @hide
*/
static final class RunQueue {
...
void executeActions(Handler handler) {
synchronized (mActions) {
final ArrayList<HandlerAction> actions = mActions;
final int count = actions.size();
for (int i = 0; i < count; i++) {
final HandlerAction handlerAction = actions.get(i);
handler.postDelayed(handlerAction.action, handlerAction.delay);
}
actions.clear();
}
}
}public final class ActivityThread {
...
final Looper mLooper = Looper.myLooper();
} void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}W/dalvikvm(796): threadid=11: thread exiting with uncaught exception (group=0x40a71930) E/AndroidRuntime(796): FATAL EXCEPTION: Thread-75 E/AndroidRuntime(796): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. E/AndroidRuntime(796): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746) E/AndroidRuntime(796): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:823) E/AndroidRuntime(796): at android.view.View.requestLayout(View.java:15473) E/AndroidRuntime(796): at android.view.View.requestLayout(View.java:15473) E/AndroidRuntime(796): at android.view.View.requestLayout(View.java:15473) E/AndroidRuntime(796): at android.view.View.requestLayout(View.java:15473) E/AndroidRuntime(796): at android.view.View.requestLayout(View.java:15473) E/AndroidRuntime(796): at android.widget.ImageView.setImageDrawable(ImageView.java:406) E/AndroidRuntime(796): at android.widget.ImageView.setImageBitmap(ImageView.java:421) E/AndroidRuntime(796): at com.example.thread01.MainActivity$2$1.run(MainActivity.java:80)
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}
/**
* 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);
}
} private static void handleCallback(Message message) {
message.callback.run();
}在分析 Looper::Loop() 这个关键函数之前,先来理一理 Thread,Looper,Handler,MessageQueue 的关系:Thread 需要有 Looper 才能处理消息(也就是说 Looper 是运行在 Thread 中),这是通过在自定义 Thread 的 run() 函数中调用 Looper::prepare() 和 Looper::loop() 来实现,然后在 Looper::loop() 中不断地从 MessageQueue 获取由 Handler 投递到其中的 Message,并调用 Message 的成员变量 Handler 的 dispatchMessage 来处理消息。
下面先来看看 Looper 的构造函数:
final MessageQueue mQueue;
final Thread mThread;
volatile boolean mRun;
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mRun = true;
mThread = Thread.currentThread();
}/**
* Initialize the current thread as a looper, marking it as an
* application‘s main looper. The main looper for your application
* is created by the Android environment, so you should never need
* to call this function yourself. See also: {@link #prepare()}
*/
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}SystemServer.java 中的 ServerThread,ServerThread 的重要性就不用说了,绝大部分 Android Service 都是这个线程中初始化的。这个线程是在 Android 启动过程中的 init2() 方法启动的:
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
class ServerThread extends Thread {
@Override
public void run() {
...
Looper.prepareMainLooper();
...
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
}public static void main(String[] args) {
....
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}有了前面的铺垫,这下我们就可以来分析 Looper::Loop() 这个关键函数了:
/**
* 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();
}
}Android多线程分析之三:Handler,Looper的实现,布布扣,bubuko.com
Android多线程分析之三:Handler,Looper的实现
原文地址:http://blog.csdn.net/kesalin/article/details/37722659