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

Android线程模型--在子线程中更新UI

2015-12-25 17:03 411 查看
Android是支持多线程的。主线程也称UI线程,子线程也称工作线程。一般耗时操作在子线程中进行,更新UI操作在主线程中进行。在主线程中执行耗时操作容易发生ANR错误,即应用程序无响应。而Android中又规定只有创建UI的线程才能更新UI,即只有主线程才能更新UI。然后,我们又听说有什么方法可以子线程中也可以更新UI。

在子线程中更新UI的方法有:

1)Activity类:public void runOnUiThread(Runable action);

2)View类:public boolean post(Runable action);

3)View类:public boolean postDelayed(Runable action,long delayMillis);

可是AndroidUI线程模型不是明确表示子线程中不能更新UI吗?这是怎么回事?结合例子,我们来看一下。

第一种在子线程中更新UI的方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivImage=(ImageView) findViewById(R.id.imageView1);
//handler=new InnerHandler();
handler=new Handler(new InnerCallback());
}
public class InnerCallback implements Handler.Callback{
@Override
public boolean handleMessage(Message msg) {
if(msg.what==LOAD_IMAGE_COMPLETED){
ivImage.setImageBitmap(bm);
}
return false;
}
}


--------------------------------------------------------------------------

第二种在子线程中更新UI的方法:

public void doLoadImage(View v){
//子线程调用View的post()方法更新ui
new Thread(){
public void run() {
//从网络中加载图片,即耗时操作
final Bitmap bm=loadImageFromNetwork();
ivImage.post(new Runnable() {
@Override
public void run() {
//更新图片显示
ivImage.setImageBitmap(bm);
}
});
};
}.start();
}


第三种与第二种类似。

子线程是不允许更新UI的,而这些方法从源代码的角度似乎是在子线程中更新UI,其实是间接的调用的主线程更新UI,并不是真的在子线程中更新UI。其主线程与子线程之间的通信采用的是消息机制。

查看其源代码可知,

public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}


---------------------------------------------------------

public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}


本质上都是调用了Handler中的post()实现线程间通信,而Handler的post()系列方法使用Runnable作为参数,其实质还是调用Handler发消息的方法实现线程间通信。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: