从应用角度看Android源码

来源:互联网 发布:淘宝加密算法 编辑:程序博客网 时间:2024/05/26 08:41

上一篇扒开AsyncTask的祖坟的时候提到了Handler,说白了AsyncTask只是对Handler进行了封装,这次就进一步研究一下Handler机制,我写了个模拟handler机制的Demo (https://github.com/wk415190639/Looper),提及handler必然涉及到Looper、Message、MessageQueue,这几个类Handler机制主要组成部分,先分析一下这个Demo

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        new ReceiveThread().start();        startActivity(new Intent(this,WorkActivity.class));    }}

MainActivity 里做了两件事,第一是开启了模拟的UI线程,第二就是开启WorkActivity,简单到极致,没什么可说的了,看看WorkActivity里面做了什么

public class WorkActivity extends Activity  implements View.OnClickListener {    HandlerTest handlerTest = new HandlerTest() {        @Override        public void handleMessage(MessageTest msg) {            super.handleMessage(msg);            Log.i("QueueTest", Thread.currentThread().getName() + " : handleMessage : " + msg.msg);        }    };    int i = 100;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Thread.currentThread().setName("workThread");        setContentView(R.layout.activity_main);        findViewById(R.id.button).setOnClickListener(this);    }    @Override    public void onClick(View view) {        MessageTest msg = new MessageTest();        msg.msg = i++;        Log.i("QueueTest", Thread.currentThread().getName() + " : sendMessage : " + msg.msg);        handlerTest.sendMessage(msg);    }}
WorkActivity 里面先以匿名内部类的方式实例化一个HandlerTest类,这和平时我们获取handler的方式一样。在OnCreate()回调里将当前的线程名设置为workThread,这个线程原本为真正的UI线程,为了Demo的演示效果就把Android原本的UI线程和工作线程兑换了名字。接着注册了Button的点击事件,在Button的onClicks事件里发送消息。也就是让HandlerTest把消息放进消息队列。HandlerTest类也是非常简单的。

public class HandlerTest {    public LinkedBlockingDeque linkedBlockingDeque;    public HandlerTest() {        linkedBlockingDeque = LooperTest.myLooper().queue;    }    public void handleMessage(MessageTest msg) {    }    public void dispatchMessage(MessageTest msg) {        handleMessage(msg);    }    public final boolean sendMessage(MessageTest msg) {        msg.target = this;        linkedBlockingDeque.offer(msg);        return true;    }}


在handlerTest类里有三个方法sendMessage是写给工作线程通过handler调用的,这个函数主要是把Message放进了消息队列linkedBlockingDeque里,这个linkedBlockingDeque是在handlertest类构造函数里赋值的,dispatchMessage函数也是主要是为了调用handleMessage函数,可以看到handleMessage函数里是空的,他的逻辑是在WorkActivity里以匿名内部类t的方式被复写的。所以真正的逻辑是在workActivity.java里,再去看看linkedBlockingDeque的真正位置LooperTest里都做了什么


public class LooperTest {    public LinkedBlockingDeque<MessageTest> queue;    public Thread thread;    private static LooperTest looperTest;    public LooperTest() {        queue = new LinkedBlockingDeque<MessageTest>();        thread = Thread.currentThread();    }    public static void prepareMainLooper() {        if (looperTest == null)            looperTest = new LooperTest();    }    public static @Nullable LooperTest myLooper() {        return looperTest;    }        public void loop() {        for (; ; ) {            try {                Log.i("QueueTest", Thread.currentThread().getName() + " : start blocking....................");                MessageTest msg = (MessageTest) queue.take();                msg.target.dispatchMessage(msg);                Log.i("QueueTest", Thread.currentThread().getName() + " : read msg : " + msg.msg + "\n\n ");            } catch (Exception e) {                e.printStackTrace();            }        }    }}

LooperTest 在构造函数中实例化的一个消息队列,prepareMainLooper()实例化了LooperTest,myLooper()返回LooperTest实例,Loop()就是循环读取消息队列里面的数据,当消息队列为空时会一直阻塞在哪里,直到读取到消息队列中的数据,接着调用HandlerTest的dispatchMessage()方法,在dispatchMessage()调用handleMessage(),这样WorkActivity$HandlerTest 的handleMessage()就被调用了,因为是在LooperTest所在线程调用的,所以handleMessage()会运行在LooperTest所在的线程里,也就是最开始MainActivity开启的那个ReceiveThread线程,如果他是UI线程,那么handleMessage()就会运行在UI线程了。在回过来看一看在最开始的是开启的那个线程都做什么工作


public class ReceiveThread extends Thread {    public ReceiveThread() {        setName("ReceiveThread");    }    @Override    public void run() {        LooperTest.prepareMainLooper();        LooperTest looperTest = LooperTest.myLooper();        looperTest.loop();    }}

这个类主要的工作就是实例化了Looper,然后让Looper循环读取消息队列的消息,再将消息发给HandlerTest。下面送一张蜘蛛网图和点击一次的效果


I/QueueTest: ReceiveThread : start blocking....................I/QueueTest: workThread : sendMessage : 100I/QueueTest: ReceiveThread : handleMessage : 100I/QueueTest: ReceiveThread : read msg : 100                           I/QueueTest: ReceiveThread : start blocking....................

接下来看看Android源码吧

先从Handler看看吧

   Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);        }    };

这里边看似平常却暗藏玄机,去Handler的构造函数看一下
public Handler() {   this(null, false); }

 public Handler(Callback callback, boolean async) {        略。。。。。。        mLooper = Looper.myLooper();        if (mLooper == null) {            throw new RuntimeException(                "Can't create handler inside thread that has not called Looper.prepare()");        }        mQueue = mLooper.mQueue;        略。。。。。。。    }

代码里略掉了一些无关部分,构造函数里主要是获取了所在线程的Looper实例和Looper实例下的mQueue消息队列。主线程的Looper是在ActivityThread的main方法里被实例化的(下次研究一下Looper如何在ActivityThread里实例化的),ActivityThread 就相当于Demo里写的ReceiveThread的那个类,这里先不做研究。再handler是如何发送消息的,一般我们会调用sendMessage(Message msg),那就进去看看他的实现

   public final boolean sendMessage(Message msg)    {        return sendMessageDelayed(msg, 0);    }

   public final boolean sendMessageDelayed(Message msg, long delayMillis)    {        if (delayMillis < 0) {            delayMillis = 0;        }        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);    }


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

 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {        msg.target = this;        if (mAsynchronous) {            msg.setAsynchronous(true);        }        return queue.enqueueMessage(msg, uptimeMillis);    }
跟到这里可以发现Message实例的成员target被赋值为当前的handler实例,然后就把msg推进了消息队列里面,到这里消息的发送就结束了,那在去看看消息再UI线程里是怎么接收的吧,像Demo里所写的那样,Message 是在Looper 类的loop()函数里被接收的,那就跳进去看看,

 public static void loop() {        final Looper me = myLooper();        final MessageQueue queue = me.mQueue;        for (;;) {               Message msg = queue.next(); // might block               msg.target.dispatchMessage(msg);        }    }
删去了一些碍眼的代码,就剩下这几句骨干了,loop()里循环读取queueu里的数据,读到数据消息后调用message的成员对象target(也就是handler)的dispatchMessage(msg)方法,将收到的消息分发出去

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

在这里边调用了   handleMessage(msg),之后再上面写的匿名内部类(new Handler(){})的handleMessage()里就能接收到消息了。到这里handler的消息发送到接收全找到了。



原创粉丝点击