文章目录
子线程更新UI的几种方法
-
1、使用Handler
-
2、Activity.runOnUIThread()
-
3、view.post()/postDelayed()
private void show(){ if(myView.getVisibility()==View.GONE){ myView.setVisibility(View.VISIBLE); } myView.post(new Runnable() { @Override public void run() { //对view执行动画 } }); } //注:将view的可见性从GONE设置为VISIBLE时会申请requestLayout, //而layout是异步执行的,所以setVisibility方法返回了但是该操作还未完成
-
使用AsyncTask(但其实内部也是使用了Handler)
子线程使用Handler和Looper
-
通过Looper.prepare()方法会自动创建消息队列MessageQueue
-
Looper.mylooper()可以获取当前线程的looper对象
-
Message.obtain()方法可以获取到一个Message对象;Handler.obtainMessgae()方法也可以获取一个消息对象Message
new Thread(new Runnable(){
public void run(){
Looper.prepare();
Handler handler = new Handler(new Callback(){
public boolean handleMessage(Message msg){
return false;
}
});
Looper.loop();
}
});
为什么必须调用Looper.prepare()/Looper.loop()
Handler在创建的时候会调用Looper.myLoop()方法来获取当前线程的Looper对象,如果不存在则抛出异常(当然创建Handler还有一个构造函数会传递Looper对象,这个是创建的handler和传入的Looper对象对应,不再使用当前线程的Looper来创建Handler)
public Handler(Callback callback, boolean async) {
......
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
而Looper.prepare()方法会为当前线程创建Looper对象,所以必须先调用prepare()方法后才可以在该线程中 new Handler()
public static void prepare() {
prepare