zoukankan      html  css  js  c++  java
  • Android中Handler原理

    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里面的代码。

  • 相关阅读:
    java_oop_方法2
    POJ 3276 Face The Right Way(反转)
    POJ 3276 Face The Right Way(反转)
    POJ 2566 Bound Found(尺取法,前缀和)
    POJ 2566 Bound Found(尺取法,前缀和)
    POJ 3320 Jessica's Reading Problem(尺取法)
    POJ 3320 Jessica's Reading Problem(尺取法)
    POJ 3061 Subsequence(尺取法)
    POJ 3061 Subsequence(尺取法)
    HDU 1222 Wolf and Rabbit(欧几里得)
  • 原文地址:https://www.cnblogs.com/llguanli/p/8448182.html
Copyright © 2011-2022 走看看