使用Handler异步处理的内部过程

      使用Handler进行异步处理的过程见我之前写的一篇《android异步处理简单总结》,在这里我想讲一下用Handler进行异步处理的内部过程。

1、创建Handler。调用Looper.myLooper(),方法获得Looper对象。这个Looper对象是在ActivityThread类的main方法中创建的。通过源代码可以看出,在第一个Handler创建之前必然已经有Looper对象创建了。“The main looper for your application is created by the Android environment”,这是官方文档里的一句话。

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();//直接调用的myLooer(),说明已经有Looper对象了。
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = null;
    }

myLooper方法的源代码如下:

public static final Looper myLooper() {
        return (Looper)sThreadLocal.get();
    }

2、Looper和对应的MessageQueue的创建过程:

main Looper创建的源代码如下:

public static final void prepareMainLooper() {
        prepare();
        setMainLooper(myLooper());
        if (Process.supportsProcesses()) {
            myLooper().mQueue.mQuitAllowed = false;
        }
    }

要创建一个Looper必须调用prepare()方法:

public static final void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
    }

Looper的构造函数:

private Looper() {
        mQueue = new MessageQueue();//消息队列创建
        mRun = true;
        mThread = Thread.currentThread();
    }


3、Handler通过sendMessage和post方法将Message发送到消息队列中。

public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;
        if (queue != null) {
            msg.target = this;
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }


PS:post方法本质上也是sendMessage方法:

public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }


4、Looper从消息队列中循环取出消息,关将其交给Handler处理。

public static final void loop() {
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
            Message msg = queue.next(); // might block
            //if (!me.mRun) {
            //    break;
            //}
            if (msg != null) {
                if (msg.target == null) {
                    // No target is a magic identifier for the quit message.
                    return;
                }
                if (me.mLogging!= null) me.mLogging.println(
                        ">>>>> Dispatching to " + msg.target + " "
                        + msg.callback + ": " + msg.what
                        );
                msg.target.dispatchMessage(msg);//交给Handler处理
                if (me.mLogging!= null) me.mLogging.println(
                        "<<<<< Finished to    " + msg.target + " "
                        + msg.callback);
                msg.recycle();//消息使用完后进行回收到消息池中。
            }
        }
    }

5、Handler处理消息:

public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);//处理线程消息,对应post方法加入进来的线程
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);//处理普通消息,这个方法在Handler类中是一个空方法,所以我们都会重写它。
        }
    }

总结:从上面可以看到,整个内部的处理过程包括1、3、4、5四个步骤,而第二个步骤是在一开始就进行了。之所以写出来是为了便于理解。

由于个人水平有限,所以请多多指点。

参考:http://qaohao.iteye.com/blog/509145

http://www.poemcode.net/2010/03/activity-main-looper/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值