更新UI的方式
Handler的post()方法:实际调用了handler的sendMessageDelayed()
Handler的sendMessage方法
View的post()方法 实际调用了handler的post方法
Activity的runOnUiThread()方法
如果当前的线程不等于UI线程(主线程),就去调用Handler的post()方法,否则就直接调用Runnable对象的
如果当前的线程不等于UI线程(主线程),就去调用Handler的post()方法,否则就直接调用Runnable对象的run()方法。还有什么会比这更清晰明了的吗? 通过以上所有源码的分析,我们已经发现了,不管是使用哪种方法在子线程中更新UI,其实背后的原理都是相同的,必须都要借助异步消息处理的机制来实现,而我们又已经将这个机制的流程完全搞明白了,真是一件一本万利的事情啊。
方法一: view.post(Runnable action)
在子线程中更新UI
textView.post(textView.post(new Runnable() {
@Override
public void run() {
textView.setText("更新textView");
}
});
如果你的子线程里可以得到要更新的view的话,可以用此方法进行更新。
view还有一个方法view.postDelayed(Runnable action, long delayMillis)用来延迟发送
方法二:runOnUiThread(Runnable action)
假如该方法是在子线程中
注意:context 对象要是 主线程中的MainActivity,这样强转才可以。
runOnUiThread(new Runnable() {
@Override
public void run() {
//此时已在主线程中,更新UI
}
});
方法三:Handler机制
首先在主线程中定义Handler,Handler mainHandler = new Handler();(必须要在主线程中定义才能操作主线程,如果想在其他地方定义声明时要这样写Handler mainHandler = new Handler(Looper.getMainLooper()),来获取主线程的 Looper 和 Queue )
获取到 Handler 后就很简单了,用handler.post(Runnable r)方法把消息处理放在该 handler 依附的消息队列中(也就是主线程消息队列)。
(1)假如该方法是在子线程中
Handler mainHandler = Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
//已在主线程中,更新UI
}
});
Handler还有下面的方法:
1.postAtTime(Runnable r, long uptimeMillis); //在某一时刻发送消息
2.postAtDelayed(Runnable r, long delayMillis); //延迟delayMillis毫秒再发送消息
(2): 假设在主线程中
Handler myHandler = Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case 0:
//更新UI等
break;
default:
break;
}
}
}
之后可以把 mainHandler 当做参数传递在各个类之间,当需要更新UI时,可以调用sendMessage一系列方法来执行handleMessage里的操作。
子线程中发送消息到主线程更新UI
之后可以把 mainHandler 当做参数传递在各个类之间,当需要更新UI时,可以调用sendMessage一系列方法来执行handleMessage里的操作。
子线程中发送消息到主线程更新UI
/**
*获取消息,尽量用obtainMessage()方法,查看源码发现,该方法节省内存。
*不提倡用Messenger msg=new Messenger()这种方法,每次都去创建一个对象,肯定不节省内存啦!
*至于为什么该方法还存在,估计还是有存在的必要吧。(留作以后深入研究)
*/
new Thread(new Runnable(){
@Override
public void run() {
//耗时操作,完成之后发送消息给Handler,完成UI更新;
mHandler.sendEmptyMessage(0);
//需要数据传递,用下面方法;
Message msg =new Message();
msg.obj = "数据";//可以是基本类型,可以是对象,可以是List、map等;
mHandler.sendMessage(msg);
myHandler.sendEmptyMessage(0); //其实内部实现还是和上面一样
endEmptyMessageAtTime(int what, long uptimeMillis); //定时发送空消息
sendEmptyMessageDelayed(int what, long delayMillis); //延时发送空消息
sendMessageAtTime(Message msg, long uptimeMillis); //定时发送消息
sendMessageDelayed(Message msg, long delayMillis); //延时发送消息
sendMessageAtFrontOfQueue(Message msg); //最先处理消息(慎用)
}
}).start();
方法四: AsyncTask
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!