首页 > 代码库 > Android中关于Handler Looper理解

Android中关于Handler Looper理解

在Android中每个应用的UI线程是被保护的,不能在UI线程中进行耗时的操作,其他的子线程也不能直接进行UI操作。

为了达到这个目的Android设计了handler Looper这个系统框架。

首先讲解在主线程中使用Handler时源码跟踪过程。

正常在activity的oncreate函数中定义个handler,这种情况下就是默认的主线程的handler,并去复写该类的handleMessage()函数。

private final Handler mMessageHandler = new Handler(){
    @Override
    public void handleMessage(Message msg){
        ....;
    }
}

 在这里new 了一个Handler类,跟入系统代码

106    /**
107     * Default constructor associates this handler with the {@link Looper} for the
108     * current thread.
109     *
110     * If this thread does not have a looper, this handler won‘t be able to receive messages
111     * so an exception is thrown.
112     */
113    public Handler() {
114        this(null, false);
115    }
188    public Handler(Callback callback, boolean async) {
189        if (FIND_POTENTIAL_LEAKS) {
190            final Class<? extends Handler> klass = getClass();
191            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
192                    (klass.getModifiers() & Modifier.STATIC) == 0) {
193                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
194                    klass.getCanonicalName());
195            }
196        }
197
198        mLooper = Looper.myLooper();
199        if (mLooper == null) {
200            throw new RuntimeException(
201                "Can‘t create handler inside thread that has not called Looper.prepare()");
202        }
203        mQueue = mLooper.mQueue;
204        mCallback = callback;
205        mAsynchronous = async;
206    }

最后需要对mQueue;mCallback;mAsynchronous这三个变量赋值。
这里注意 mLooper = Looper.myLooper(); 对mLooper的初始化。这里进入了Looper类

191    public static @Nullable Looper myLooper() {
192        return sThreadLocal.get();
193    }
68    // sThreadLocal.get() will return null unless you‘ve called prepare().
69    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
92    private static void prepare(boolean quitAllowed) {
93        if (sThreadLocal.get() != null) {
94            throw new RuntimeException("Only one Looper may be created per thread");
95        }
96        sThreadLocal.set(new Looper(quitAllowed));
97    }
98

最后new Looper(quitAllowed) 在这里在当前thread中新建了一个Looper对象(所以从这里可以看出来Looper是属于当前thread的)。
正常在我们自己new的线程中都需要调用Looper.prepare();语句来为当前线程new一个looper对象。但是对于UI线程中创建的looper是不需要的,因为在初始化UI线程时就已经写好了。

正常UI线程初始化时调用prepareMainLooper这个函数。

99    /**
100     * Initialize the current thread as a looper, marking it as an
101     * application‘s main looper. The main looper for your application
102     * is created by the Android environment, so you should never need
103     * to call this function yourself.  See also: {@link #prepare()}
104     */
105    public static void prepareMainLooper() {
106        prepare(false);
107        synchronized (Looper.class) {
108            if (sMainLooper != null) {
109                throw new IllegalStateException("The main Looper has already been prepared.");
110            }
111            sMainLooper = myLooper();
112        }
113    }

对于一般的子线程需要继续调用Looper.loop来启动loop循环进行消息发送。
而同样对于UI线程的looper同样是在初始化过程中已经调用好了。

128    public static void loop() {
129        final Looper me = myLooper();
130        if (me == null) {
131            throw new RuntimeException("No Looper; Looper.prepare() wasn‘t called on this thread.");
132        }
133        final MessageQueue queue = me.mQueue;
..............
142        for (;;) {
143            Message msg = queue.next(); // might block
144            if (msg == null) {
145                // No message indicates that the message queue is quitting.
146                return;
147            }
。。。。。。。。。。
158            msg.target.dispatchMessage(msg);

在这个loop()函数中就能真正看到消息循环机制。在一个死循环中for(;;)不断从queue消息队列中获取messager,如果没有将阻止在该端口等待下一个messager。
在获取一个消息后则放入message中的targe中进行消息分发。

这里的target其实就是最开始在封装一个message进行发送时传入的handler,所以从这里也可以看出,最后消息还是通过handler传入到它所在的线程中调用handleMessage()进行处理。

message.java 的成员变量:

public final class Message implements Parcelable {
   public int what;
   public int arg1;
   public int arg2;
   public Object obj;
   public Messenger replyTo;
   public int sendingUid = -1;
   /*package*/ static final int FLAG_IN_USE = 1 << 0;
   /** If set message is asynchronous */
   /*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;
   /** Flags to clear in the copyFrom method */
   /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;
   /*package*/ int flags;
   /*package*/ long when;
   /*package*/ Bundle data;
   /*package*/ Handler target
   /*package*/ Runnable callback;
   // sometimes we store linked lists of these things
   /*package*/ Message next;


。。。。

 

Android中关于Handler Looper理解