您的位置:首页 > 产品设计 > UI/UE

Handler.post(runnable)内更新UI

2018-01-10 17:28 323 查看
可参考http://blog.csdn.net/tantion/article/details/54629854
handler.post(Runnable r)方法,
分析源码:
public final boolean post(Runnable r) {
        return  sendMessageDelayed(getPostMessage(r), 0);
}

getPostMessage(r)方法, 给message设置了回调:
private static Message getPostMessage(Runnable r) {  
        Message m = Message.obtain();  
        m.callback = r;  
        return m;  
}

然后,looper进行消息循环,进行消息的分发:

public void dispatchMessage(Message msg) {  
    if (msg.callback != null) {  
        handleCallback(msg);  
    } else {  
        if (mCallback != null) {  
            if (mCallback.handleMessage(msg)) {  
                return;  
            }  
        }  
        handleMessage(msg);  
    }  
}
//handler在分发消息时,做了判断,看当前message的callback有没有值,如果有则执行给的回调,
//否则调用具体实现类的handleMessage方法

如果回调不为空,handleCallback(msg) 找个方法就会执行,
private static void handleCallback(Message message) {  
        message.callback.run();  
}  //调用了run方法

handler在分发消息时,做了判断,看当前message的callback有没有值,如果有则执行给的回调,否则调用具体实现类的handleMessage方法。
那么handler.post(runnable)方法其实也是会创建一个message,让后把message的callback属性值设置为当前方法接收到的runnable参数,而不是开启新线程,不要顾名思义。

handler.post(runnable)与handler.sendMessage()系列方法区别在于:
用前者的形式时,handler不需要实现handleMessage方法,runnable的类体代替了。
用后者则handler必须实现handleMessage方法,不然怎么处理收到的消息

so, handler.post(runnable)它是在主线程中处理的, 

msg.callback = runnable-->dispatchMessage(msg)-->

handleCallback(msg)-->message.callback.run();  //(即普通方法run, 非start())

销毁的方法:  handler.removeCallbacks(run);

参考 http://blog.csdn.net/u013136708/article/details/50607945
handler.post(Runnable r)方法是将Runnable对象发送到主线程中执行,并且源码注释如下* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached. 注释的意思是runnable会在handler所在的线程中执行。按照注释的意思以及我们经常使用的情况来看,runnable的逻辑无疑是在主线程中执行的。

new MyRunnable().run();                          //此时 ThreadId等于主线程ID
new Thread(new MyRunnable()).start();   //此时 ThreadId 不等于主线程ID,  so run方法为普通复写,start方法新启动一个线程
public static class MyRunnable implements Runnable{
        public void run() {
                System.out.println("runnable thread id = " + Thread.currentThread().getId());
        }
}

runnable.run()方法逻辑的执行际上是在runnable所在的线程中的执行的,runnable并不会新开辟一个子线程。runnable中的逻辑实际上是在主线程中执行的,要是runnable逻辑出现阻塞,那么主线程也会相应的被阻塞。而Thread就是完全开辟了一个子线程了,线程ID发生了变化。

回到问题,handler.post方法可以进行UI修改,但是里面的逻辑是在主线程中执行的,要是有耗时操作,会阻塞主线程,导致点击事件无响应等,所以handler.post可以用作修改UI,但是不应该用Handler.post执行一些复杂的逻辑。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: