一个线程创建消息循环的步骤
Looper.perpareLoop();
Handler mhandler = new Handler();
Looper.loop();
首先prepare是一个静态函数,可以不实例化对象进行访问
private static final ThreadLocal sThreadLocal = new ThreadLocal();
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
final MessageQueue mQueue;
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
final MessageQueue mQueue;
final Looper mLooper;
public Handler() {
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();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}
首先它会使用ThreadLocal变量,关于ThreadLocal,它的作用是使每个线程获得安全的变量拷贝(里面的具体实现应该会有加锁,通过Map实现一些存储,只是猜测没有看具体代码)
ps:其实使用ThreadLocal也是为了代码实现简单,不复杂,尽量结构化
从代码中可以看出,在Looper创建的时候同时创建的MessageQueue,
在创建Handler的时候通过Looper.myLooper();获得了looper的实例(内部实现应该是类似于map的数据结构存储了线程的id,获得了looper,以及messagequeue)
同时初始化了mCallback.
剩下的就是handler发送消息的操作,首先它会sendmessage(msg),这时会调用到enqueuemessage将消息加入到队列,加入完成之后messagequeue的next函数会被唤醒,进行消息分发,同时looper的阻塞函数也会被唤醒,进行消息的处理
msg.target.dispatchMessage(),让handler对消息进行处理。
注意:关于messagequeue的实现其实并不是我们想象的那样简单,如果深入的jni层的话,最后会看到它是用linux层去实现的
http://www.cnblogs.com/angeldevil/p/3340644.html
Native层的Looper使用了epoll。初始化了一个管道,用mWakeWritePipeFd与mWakeReadPipeFd分别保存了管道的写端与读端,并监听了读端的EPOLLIN事件。注意下初始化列表的值,mAllowNonCallbacks的值为false。
上面这篇博客还是讲解的比较清晰,从java层到c++层,让我们了解到了android系统最本质的东西