AndroidUI界面更新的四种方式:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView textView;
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
textView.setText("updateUI2");
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.txt_view);
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(2000);
updateUI1();
Thread.sleep(2000);
updateUI2();
Thread.sleep(2000);
updateUI3();
Thread.sleep(2000);
updateUI4();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
/**
* 内部实现与2相同,都是通过Message传递
*/
private void updateUI1(){
handler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
textView.setText("updateUI1");
}
});
}
/**
* 最常见的方法
*/
private void updateUI2(){
handler.sendEmptyMessage(1);
}
/**
* 内部同样采用handler机制处理
*/
private void updateUI3(){
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
textView.setText("updateUI3");
}
});
}
/**
* 本质还是采用handler机制处理
*/
private void updateUI4(){
textView.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
textView.setText("updateUI4");
}
});
}
}
---------------------------------------------------------------------------------------------------------------------------------
Android非UI线程真的不能更新UI吗?
将上面的UI更新代码分别修改为下面两种方式:
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(2000);
textView.setText("ok");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try {
textView.setText("ok");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
第一种程序报错,提示不能再非UI线程中更新UI。而第二种则正常对textView进行了更新。
如果大家看过setText()方法的源码就会知道有这样一个判断,在更新TextView的值时会判断当前线程是否是UI线程,如果不是就会报错。但是下面的方法是在非UI线程中更新UI为什么不报错,这是因为在判断线程的时候会用到ViewRootImpl,而ViewRootImpl的创建是在Activity的onResume方法(创建Activity窗口)中创建的,在执行上面第二段的代码是还没有执行onResume方法,所以在判断语句(更新UI的线程等于主线程)的时候,不打印错误提醒。如果有延迟的话onResume方法已经完成了ViewRootImpl的创建。
虽然,通过上面的验证可以在非UI线程中更新UI,但我们并不建议这样做。