Only the original thread that created a view hierarchy can touch its views
activity/service启动时,会启动三个线程。一个主线程和两个Binder线程
主线程在ActivityThread的main方法中启动,会调用
Looper.prepareMainLooper();方法
在该方法中会调用
sMainLooper = myLooper();
给sMainLooper赋值,与当前主线程进行绑定
public static void main(String[] args) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); AndroidKeyStoreProvider.install(); // Make sure TrustedCertificateStore looks in the right place for CA certificates final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } // End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
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)); //创建出Looper对象,并于当前线程进行绑定,set进ThreadLocal中
}
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;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}
app启动后调用Lopper类中的looper方法
通过MyLooper()创建当前线程(app启动时默认主线程,以后是Looper对象所在线程)的looper对象
创建MessageQueue对象,与Looper类中MessageQueue成员变量共享同一内存空间,me.mQueue被改变时,MessageQueue对象随之改变
创建死循环,不断的从MessageQueue队列中取出message对象,为空则阻塞
通过msg.target.dispatchMessage(msg)进行消息的分发,调用该msg所在handler对象的handleMessage方法(target在message入队时已被赋值:Handler类的enqueueMessage()方法中完成target赋值)
整个过程都是在主线程中完成的,所以说子线程如果要创建自己的Looper对象,则需要在自线程中调用loop()方法
子线程给主线程及子线程给子线程传递数据
Handler中传入的Looper与哪个线程进行绑定,消息就传入哪个线程中进行处理
eg:
Looper.getMainLooper()获得的Looper对象与主线程进行绑定,可以在子线程中sendMessage,handlerMessage()所处线程是主线程
Looper.prepare()获得与当前线程绑定的Looper对象,
如果是在主线程中,则与Looper.getMainLooper()一致。
如果是在子线程中,则是与子线程进行通信(子与子通信),最后还需调用Looper.loop()进行创建该线程的Looper对象。
Looper.myLooper()可以获得该Looper对象。如果直不执行Looper.prepare()而直接执行Looper.myLooper()则会空指针异常。
Looper不断获取MessageQueue中的一个Message,然后由Handler来处理。
中央处理器(Looper)从内存(MessageQueue)中取出指令(Message),执行指令(Handler).
一.每个Thread只对应一个Looper
二.每个Looper只对应一个MessageQueue
三.每个MessageQueue中对应n个Message
四.每个Message中最多指定一个Handler来处理事件(多个Message可以指定同一个Handler处理)
所以
一个Thread对应多个Handler
handler得两个功能
一.处理Message
具体方法:
1.public void dispatchMessage(Message msg)
2.public void handleMessage(Message msg)
Looper从MessageQueue中取出一个Message后,首先会调用Handler.dispatchMessage进行消息派发
然后调用handlerMessage来进行处理
二.将某个Message压入MessageQueue中
具体方法:
1.Post系列
post(Runnable r)
postAtTime(Runnable r,long uptimeMillis)
2.Send系列
sendEmptyMessage(int what)
sendMessageDelayed
sendMessageAtFrontofQueue
sendMessageAtTime
区别:
post需要把Runnable先包装成一个Message 然后再发送。
Handler-->MessageQueue-->Message-->Handler
这体现了程序设计的有序性
eg:健身房事件,你正在健身房跑步,朋友找你借钱
两种处理方式
1.停止健身,借钱给他
2.秘书加入事件处理队列,按优先级等你健身完毕再交给你处理
如果健身一小时100万,朋友借钱100,你就没必要马上处理。
======================
程序中使用Looper有两种情况
一.主线程中使用
二.