1.在子线程中使用Handler实例
/***********子线程使用Handler实例*********/ private class LooperThread extends Thread { public Handler handler; @Override public void run() { Looper.prepare(); handler = new Handler() { @Override public void handleMessage(Message msg) { } }; Looper.loop(); } }
public static void main(String[] args) { //前面一系列配置暂时不用关心 SamplingProfilerIntegration.start(); CloseGuard.setEnabled(false); Environment.initForCurrentUser(); EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0("<pre-initialized>"); /************从这里开始,使用Looper*******************/ Looper.prepareMainLooper();//对比:子线程中使用Looper.prepare(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler();//对比:子线程中自创建new Handler() } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop();//对比:这里两者相同 throw new RuntimeException("Main thread loop unexpectedly exited"); }
/** 将当前线程初始化为一个Looper.所以你可以在start loop前先创建Handlers,再引用这个looper; * 要确保在调用本方法后调用#loop()方法;结束本方法使用#quit(); */ public static void prepare() { prepare(true); //对比:下面将会看到主线程中的prepareMainLooper中将会使用prepare(false) } 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)); }附I)这里引出了一个sThreadLocal,首先看其定义:
// sThreadLocal.get() will return null unless you've called prepare(). static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
/** * 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) { thrownew IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } /** * 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(); }附II): sMainLooper的定义:
private static Looper sMainLooper;
和前面大致相同,只是定义了一个sMainLooper,get sThreadLocal获得一个Looper,让sMainLooper指向它;
(二)Handler
1、Handler部分源码:
Handler众多构造函数:
public Handler() { this(null, false); } public Handler(Callback callback) { this(callback, false); } public Handler(Looper looper) { this(looper, null, false); } public Handler(Looper looper, Callback callback) { this(looper, callback, false); } public Handler(boolean async) { this(null, async); } public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; } /****************重点看此构造函数*********************/ public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } /***************前面忽略,从这里开始看******************/ mLooper = Looper.myLooper();//依然通过sThreadLocal获取到当前Thread的Looper实例,可见这里两者联系到一起 if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; //这里MessageQueue是Looper与Handler沟通的桥梁 mCallback = callback; mAsynchronous = async; }附I)mQueue的定义:final MessageQueue mQueue;
可见通过MessageQueue,Handler与Looper联系到一起;
而观察源码可以发现Handler中常用的发送Message的方法如sendMessage等,最终的实现均是Message的enqueue操作,即进入MessageQueue队列。
public static void loop() { final Looper me = myLooper();//依然通过sThreadLocal获取到当前Thread的Looper实例 if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue;//获取到上面提到过的MessageQueue mQueue Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); /****************循环处理消息*******************/ for (;;) { Message msg = queue.next(); // 从MessageQueue中取出next消息 if (msg == null) { // No message indicates that the message queue is quitting. //表明当前MessageQueue正在退出 return; } // 调试信息,跳过 Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } /** 开始分派消息*/ msg.target.dispatchMessage(msg);//Message中的定义Handler target,故dispatchMessage //最终调用Handler中的处理函数; /** 调试信息,跳过*/ if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } 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();//回收处理完的消息Message } }
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } // 可以看到这里最终调用重写的函数handleMessage对Message进行处理 handleMessage(msg); } }可以看到具体的处理逻辑,如果Message的callback不为空的话,则调用handleCallback方法,即调用Message的callback(Runnable);
private static void handleCallback(Message message) { message.callback.run(); }注意这里直接调用callback的run函数,也就是该事件的处理仍然在Handler所在的线程中。
// Message.java public static Message obtain(Handler h, Runnable callback) { Message m = obtain(); m.target = h; m.callback = callback; return m; }如果Message没有设置callback,则会接着判断Handler是否设置Callback;如果Handler设置了Callback则会优先处理callback再去处理handleMessage;
// Handler.java public Handler(Callback callback) { this(callback, 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; }其实平时在使用handler去post一个Runnable的方法,就是通过设置callback来实现的:
// Handler.java public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
private Looper(boolean quitAllowed) { //构造函数是private的 mQueue = new MessageQueue(quitAllowed);//MessageQueue是Looper创建时就被创建出来的 mThread = Thread.currentThread(); //mThread为当前线程,即Looper与当前线程建立联系 }由上loop()方法可以简单得出结论,Looper用以处理MessageQueue中的取出的Message,由MessageQueue是Handler及Looper所共用的,取出的Message则交由Handler进行处理。而Handler也能够通过post或者send等方式将Message添加到MessageQueue中供Looper后续进行取出处理。sThreadLocal保证了Looper是线程私有的,所有信息发送与处理都是在本线程中。
prepare()用以在sThreadLocal中创建线程与该线程对应的Looper的键值对;new Handler或者getHandler创建的Handler都根据sThreadLocal.get()进行获取;创建的Handler与Looper共用MessageQueue;loop开始循环处理Messagequeue中的事件。其即为整个流程。