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执行一些复杂的逻辑。
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执行一些复杂的逻辑。
相关文章推荐
- Android开发中更新UI时runOnUIthread(Runnable)与Handler.post(Runnable)的区别及如何选择
- android线程控制UI更新(Handler 、post()、postDelayed()、postAtTime)
- Handler post()等在子线程中更新主线程的UI的方法使用小汇
- Android Handler中的handleMessage方法和post方法之源码剖析 及UI更新方法
- Android:UI更新方法一:Handler+View.invalidate+Thread+Runnable
- Android:UI更新方法二:View.postInvalidate+Thread+Runnable
- 利用handler.post()更新UI
- 利用handler.post()更新UI
- android线程控制UI更新(Handler、post()、postDelayed()、postAtTime)
- android线程控制UI更新(Handler 、post()、postDelayed()、postAtTime)
- android使用post(Runnable)更新UI的误区
- android线程控制UI更新(Handler 、post()、postDelayed()、postAtTime)
- Android Handler.post 难道真的可以在子线程更新UI???
- 线程里更新UI的两种方法:Thread+Handler和Runnable
- Runnable接口实现线程,Handler消息队列更新UI
- Handler.post()解决非主线程更新UI
- android中Handler、Thread、Runnable更新UI的思考
- handler.post(Runnable r) 会阻塞UI线程。
- android线程控制UI更新(Handler 、post()、postDelayed()、postAtTime)
- 2个更新UI的方法--activity.runOnUiThread及handler.post