在Android中,只能通过主线程更新UI。而主线程中又不能进行耗时操作,不然就会报ANR(无响应)。那么耗时操作就只能放到子线程中去完成,完成后再通知主线程去更新UI。
那么子线程如何通知主线程呢?Android提供了Handler来实现这个操作。
Handler不仅能进行主线程之间、主线程与子线程之间还能进行子线程与子线程之间进行通信。那么它是如何实现的呢?在使用Handler的过程中有四个对象非常重要:Handler、Looper、Message、MessageQueue、ThreadLocal(用于存储Thread全局的本地变量)
在子线程创建Handler的时候需要在创建前调用Looper.prepare(),使用后调用Looper.loop()方法。不然Handler没法使用,两个都是必须的。如果Looper.prepare()没调用就会报异常,如果Looper.prepare()调用了而Looper.loop()没有调用handleMessage中就收不到消息。为什么呢?在Handler的构造函数中会判断调用Looper的myLooper,而在Handler的构造函数中会判断Looper是否为空,如果为空就会抛出异常。Looper对象中有一个loop()方法,这个方法中有一个死循环,从MesssageQueue中取出Message,并通过Handler把消息分发出去。
那么我们在主线程中创建Handler的时候为什么不用调用Looper.prepare()和Looper.loop()呢?因为App在启动的时候在Activity中的ActivityThread中已经帮我们创建好了,所以能够直接使用。
Handler通过sendMessage发送消息,并把Message存入MessageQueue。通过Loop的loop()方法把Message从MessageQueue中取出来,并通过Handler分发出去。
在创建在创建Looper.prepare()的的时候,会创建一个MessageQueue。ThreadLocal会把这个创建好的Looper存储起来。
网友评论