1.handler message 的原理:
a 画面的更新都是在主线程中进行的 如果其他线程也可以更新ui将导致ui显示的混乱
b 如果其他thread 想要更新UI 需要拿到hanlder 然后向消息队列 中扔这个消息 这个效率的内容可以使 int (简单的 结果或者状态 )也可以是object (这样什么都可以扔了) ui的更新还有由 主线程来做

2.View.post 函数的过程:
a View 拿到当前的handler
b handler把参数runable包装为一个 Message 并将他扔到 UI线程的消息队列中 这样 UI线程就可以适时处理这个runable了
源码如下:
public boolean post(Runnable action) {
Handler handler;
AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
handler = attachInfo.mHandler;
} else {
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
return handler.post(action);
}
注意:
a 不要在runable中执行复杂的逻辑!
b runable不是开一个线程 只不过是一个接口而已
测试:
textview.post(new Runnable() {@Overridepublic void run() {while (true) {Log.e("TEST", " runable");}}});
UI线程依旧会被阻塞
另外还有一个View.postDelayed方法:
这样可以 1s后显示append
textview.postDelayed(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}textview.append("------After");}}, 1000);
3.不得不说handler.post(new Runnable()的作用了其实很明显就是用handler向消息队列中扔被包装的runable的 消息
于是 下面就是延时 1s 执行append的操作:
handler.postDelayed(new Runnable() {@Overridepublic void run() {textview.append("Hello World");}}, 1000);
4. 消息队列MQ底层 是通过管道pipe实现
5.looper.prepare() 后就可以把一个线程绑定为一个looper线程 其实是 在looper 的ThreadLocal中把这个对象放进去
public class Looper {
// 每个线程中的Looper对象其实是一个ThreadLocal,即线程本地存储(TLS)对象
private static final ThreadLocal sThreadLocal = new ThreadLocal();
// Looper内的消息队列
final MessageQueue mQueue;
// 当前线程
Thread mThread;
// 。。。其他属性
// 每个Looper对象中有它的消息队列,和它所属的线程
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
// 我们调用该方法会在调用线程的TLS中创建Looper对象
public static final void prepare() {
if (sThreadLocal.get() != null) {
// 试图在有Looper的线程中再次创建Looper将抛出异常
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
// 其他方法
}
参考博客
android的消息处理机制(图+源码分析)——Looper,Handler,Message