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联系到一起;
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
}
}
Handler,Looper,Message,MessageQueue之间关系浅析
原文:http://blog.csdn.net/woliuyunyicai/article/details/46513821