Handler主要是主线程和子线程通信。一般子线程中做一些耗时操作做完之后通知主线程来修改UI。

实际上android系统在Activity启动或者状态变化等都是通过Handler机制实现的。

首先进入到ActivityThread的main方法中

public static void main(String[] args) {        ……        Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        if (sMainThreadHandler == null) {            sMainThreadHandler = thread.getHandler();        }……        Looper.loop();……}

下面主要分析上面几句代码。

1.Looper.prepareMainLooper();

public static void prepareMainLooper() {        prepare(false);        synchronized (Looper.class) {            if (sMainLooper != null) {                throw new IllegalStateException("The main Looper has already been prepared.");            }            sMainLooper = myLooper();        }}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对象    }

Looper的构造函数如下

private Looper(boolean quitAllowed) {        mQueue = new MessageQueue(quitAllowed);//Looper维护了一个消息队列        mRun = true;        mThread = Thread.currentThread();}

小结:在调用完Loop.prepare后,就会为当前线程创建一个消息泵Looper,这个Looper维护了一个消息队列MessageQueue

2. sMainThreadHandler =thread.getHandler();

sMainThreadHandler是Handler对象,getHandler方法如下:

final Handler getHandler() {        return mH;    }

看到mH在前面定义为final H mH = new H();实际上H是继承自Handler。部分代码如下:

private class H extends Handler {        public static final int LAUNCH_ACTIVITY         = 100;        public static final int PAUSE_ACTIVITY          = 101;        ……public void handleMessage(Message msg) {            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));            switch (msg.what) {                case LAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;                    r.packageInfo = getPackageInfoNoCheck(                            r.activityInfo.applicationInfo, r.compatInfo);                    handleLaunchActivity(r, null);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;                ……}……}

小结:这里相当于平时在UI线程中创建一个Handler实现他的handlerMessage方法。

3.Looper.loop();

public static void loop() {        ……        final MessageQueue queue = me.mQueue;        for (;;) {            Message msg = queue.next(); // might block            if (msg == null) {                return;            }            ……            msg.target.dispatchMessage(msg);……            msg.recycle();        }}

小结:调用Looper.loop(),可以看到for循环,不停地从消息队列中取消息,然后分发msg.target.dispatchMessage(msg); 这里的msg.target就是Handler对象,指的是处理该Message的Handler。

public void dispatchMessage(Message msg) {        if (msg.callback != null) {            handleCallback(msg);        } else {            if (mCallback != null) {                if (mCallback.handleMessage(msg)) {                    return;                }            }            handleMessage(msg);        }    }

调用dispatchMessage,如果Message设置了回调函数就执行回调,否则如果定义Handler的时候如果传进了回调函数就执行传进的回调,不然就会执行handlerMessage函数,可以看到是有优先级顺序的。系统处理的时候由于未设置回调,就会执行handlerMessage。

比如上面的当收到LAUNCH_ACTIVITY消息,就会执行handleLaunchActivity---- performLaunchActivity---- mInstrumentation.newActivity(cl,component.getClassName(), r.intent); -----mInstrumentation.callActivityOnCreate(activity,r.state); ----- activity.performCreate(icicle);

这样就执行到了我们平时所谓的Activity的入口onCreate方法。


到现在我们看到了Handler机制在android中的应用。接下来分析一下handler和Looper是怎么关联起来的。

Handler的构造函数最终都会去执行

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();//获取当前线程的Looper        if (mLooper == null) {            throw new RuntimeException(                "Can't create handler inside thread that has not called Looper.prepare()");        }        mQueue = mLooper.mQueue;//将Looper对象的消息队列传给Handler的成员,使得Handler就可以操作该消息循环        mCallback = callback;        mAsynchronous = async;}

Message类如下

public final class Message implements Parcelable {    public int what;    public int arg1;     public int arg2;    ……    Handler target;     //每个消息都有一个成员保存和他关联的Handler    Runnable callback;   }

接下来我们看一下调用handler的sendMessage送消息时发生了什么

public final boolean sendMessage(Message msg)    {        return sendMessageDelayed(msg, 0);    }
最后会执行到:

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {        msg.target = this;//在这里将this复制给Message的Handler成员,this也就是我们定义的handler对象。        if (mAsynchronous) {            msg.setAsynchronous(true);        }        return queue.enqueueMessage(msg, uptimeMillis);//然后添加到消息队列里面    }

msg.target = this;所以就有了在loop消息循环函数中的msg.target.dispatchMessage(msg);来分发消息。由于多台就会执行我们实现的handlerMessage里面的代码。

更多相关文章

  1. Android+NDK+OpenGLES开发环境配置
  2. android 在源码中编译工程的方法
  3. Android(安卓)更新UI的两种方法——handler和runOnUiThread()
  4. android Toast大全(五种情形)
  5. Android(安卓)Touch事件分发过程
  6. 你真的了解AsyncTask吗?AsyncTask源码分析
  7. 9.5android线程优先级,go和rust比较
  8. Android(安卓)线程 Looper.prepare()、Looper.loop()
  9. android webview js不执行原因解析

随机推荐

  1. 如何查看Android的ANR(无响应)异常
  2. Android中使用定时器TimerTask类介绍
  3. Android中的Drawable基础与自定义Drawabl
  4. android第二天晚:电话和短信
  5. HTML5 实现Android app样例
  6. Android实现图片轮播
  7. Android(安卓)display架构分析(四)
  8. Android动画效果translate、scale、alpha
  9. Android 开发指南以及翻译API等
  10. 横竖屏