我这里做一个简要的笔记总结:

应用程序的主线程中会始终存在一个Looper对象,从而不需要再手动去调用Looper.prepare()方法.
总结一下就是在主线程中可以直接创建Handler对象,而在子线程中需要先调用Looper.prepare()才能创建Handler对象.

尝试在程序中创建两个Handler对象,一个在主线程中创建,一个在子线程中创建.
在子线程中创建的Handler是会导致程序崩溃的,提示的错误信息为 Can’t create handler inside thread that has not called Looper.prepare() 。

new Thread(new Runnable() {  
    @Override  
    public void run() {  
        Looper.prepare();  
        handler2 = new Handler();  
    }  
}).start();

在Handler的构造函数中,会调用Looper.myLooper()来获取一个Looper对象。如果Looper对象为空,则会抛出一个运行时异常,提示的错误正是 Can’t create handler inside thread that has not called Looper.prepare()。

而Looper.prepare()方法可以为其生成一个Looper对象。所以我们要先调用Looper.prepare()方法,才能创建Handler对象。

而在UI主线程则不用调用Looper.prepare(),因为ActivityThread(如果你不知道ActivityThread是什么,可以阅读我的上篇阅读笔记–Framework框架:重要类,APK运行过程,客户端的线程 )中的main()方法会调用Looper.prepare(),不需要再手动去调用Looper.prepare()方法。

Handler.sendMessage()方法发送出去,然后在Handler.handMessage()里面进行消息处理。
其实是这样的:
Handler.sendMessage() 会把参数message和延迟时间uptimemillis传到MessageQueue的enqueueMessage(message,uptimemillis)。MessageQueue它是一个消息队列,用于将所有收到的消息以队列的形式进行排列,并提供入队和出队的方法。
1.MessageQueue并没有使用一个集合把所有的消息都保存起来,它只使用了一个mMessages对象表示当前待处理的消息,用next属性指定了下一个消息(形成一个队里),入队其实就是将所有的消息按时间来进行排序,调用msg.next,从而为每一个消息指定它的下一个消息是什么.它的简单逻辑就是如果当前MessageQueue中存在mMessages(即待处理消息),就将这个消息出队,然后让下一条消息成为mMessages,否则就进入一个阻塞状态,一直等到有新的消息入队。每当有一个消息出队,就将它传递到msg.target的dispatchMessage()。

这是源码:

public void dispatchMessage(Message msg) {  
    if (msg.callback != null) {  
        handleCallback(msg);  
    } else {  
        if (mCallback != null) {  
            if (mCallback.handleMessage(msg)) {  
                return;  
            }  
        }  
        handleMessage(msg);  //这里就回到了最原始的handler.handleMessage(msg)方法了。
    }  
}

在Handler的dispatchMessage()方法中原来有做一个检查,如果Message的callback等于null才会去调用handleMessage()方法,否则就调用handleCallback()方法。

使用异步消息处理的方式就可以对UI进行操作:
由于Handler总是依附所在线程的,在子线程是无法操作ui的,于是通过发送消息,入队,出队,最后调用handleMessage(msg)的时候,是在主线程运行的,所有实现了UI的操作。

除了发送消息之外,我们还有以下几种方法可以在子线程中进行UI操作:
1.Handler的post()方法
实际就是调用sendMessageDelayed(getPostMessage(r), 0); 并且为Message设置一个CallBack回调。在dispatchMessage里面,CallBack不为空,则调用。

2.View的post()方法
实际就是调用Handler的post()方法。

3.Activity的runOnUiThread()方法
实际就是调用Handler的post()方法。或者直接调用runnable.run();(在主线程)