几者的关系:
每个Thread只对应一个Looper;
每个Looper只对应一个MessageQueue;
每个MessageQueue中有N个Messsage;
每个Message最多指定一个Handler来处理事件。
Handler的功能:
1.处理Message;
handlerMessage(msg);
dispatchMessage(msg);
2.将Message压入MessageQueue(为什么要先压入queue中,而不是直接处理,这体现了程序设计的“有序性”);
post(runnable);
sendMessage(msg);
post是将runnable转换成message送入messageQueue中。
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r),0);
}
private static Message getPostMessage(Runnable r){
Message m = Message.obtain();//Android系统维护的全局Message池。避免资源浪费。
m.callback = r;
return m;
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis){
MessageQueue queue = mQueue;
msg.target = this;
return enqueueMessage(queue, msg, uptimeMillis);
}
Looper的使用:
class LooperThread extends Thread{
public Handler mHandler;
public void run(){
Looper.prepare();
mHandler = new Handler(){
public void handlerMessage(){
//TODO
}
};
Looper.loop();
}
}
默认的线程不存在消息循环,所以不用使用Looper。
Looper的创建:
//Looper中的代码
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<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是在这里new的,可是它怎么和thread关联上的呢,看下面的代码:
//ThreadLocal.java
public void set(T value) {
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values == null) {
values = initializeValues(currentThread);
}
values.put(this, value);
}
这里获取了当前线程,put中做了一系列操作,将当前线程与looper关联了起来。
MessageQueue的创建:
MessageQueue在创建Looper对象的时候创建。
//Looper.java
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
Handler中获取Looper:
//Handler.java
public Handler(){
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
}
//Looper.java
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
//ThreadLocal.java
public T get() {
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values != null) {
Object[] table = values.table;
int index = hash & values.mask;
if (this.reference == table[index]) {
return (T) table[index + 1];
}
} else {
values = initializeValues(currentThread);
}
return (T) values.getAfterMiss(this);
}
Handler的构造函数中最终调用sTreadLocal.get(),get()可见也是根据当前线程获取当前的looper。
ActivityThread:
ActivityThread的mani()是进程的入口函数。
//ActivityThread.java
public static final void main(String[] args) {
SamplingProfilerIntegration.start();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
Looper.loop();
if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
Log.i(TAG, "Main thread of " + name + " is now exiting");
}
//Looper.java
public static final void prepareMainLooper() {
prepare();
setMainLooper(myLooper());
if (Process.supportsProcesses()) {
myLooper().mQueue.mQuitAllowed = false;
}
}
private synchronized static void setMainLooper(Looper looper) {
mMainLooper = looper;
}
这个主线程和普通线程的区别就是多了个Looper.prepareMainLooper();我感觉它的作用就是为了创建一个mainLooper供其他线程调用。
Looper.loop(),apk动起来的根本原因:
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while (true) {
Message msg = queue.next();
if (msg != null) {
if (msg.target == null) {
return;
}
if (me.mLogging!= null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg);
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
}
}
}
msg.target为将msg压入queue的handler
Handler处理Message:
//Handler.java
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private final void handleCallback(Message message) {
message.callback.run();
}
dispatchMessage()中,判断msg.callback不空的话,就handlerCallback(msg),此时的msg.callback即为上面post时的runnable,所以这里走的是runnable的run()方法。
else中调用的即是重写的handlerMessage()。View为什么也可以post(runnable):
public boolean post(Runnable action) {
Handler handler;
if (mAttachInfo != null) {
handler = mAttachInfo.mHandler;
} else {
ViewRoot.getRunQueue().post(action);
return true;
}
return handler.post(action);
}
View中也有post()方法,里面新建了个handler,做了post操作。