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

关于UI线程与非UI线程交互,有关Handler机制等(一)

2014-12-02 11:04 281 查看
在Android中,一个activity有一个主线程也叫UI线程,作用就是用来绘制UI界面,在这个线程里面,你的应用和android的UI组件发生交互。所以当你需要进行某些费时操作的时候,比如访问网络等,如果放入UI线程,就会阻塞界面的绘制,当界面不能绘制的时候,整个app看起来就跟卡死一样,更可怕的是,当UI线程挂起时间太长,就会发生ANR。这显然不是一种好的用户体验。另外,UI组件也并不是线程安全的,所以也最好不建议从非UI线程调用UI组件。故我们需要记住以下两点。

1.不要在UI线程里面写费时操作,导致UI线程阻塞

2.不要在非UI线程对绘制界面,可能会导致某些错误

非UI线程也被称作为工作线程,后台线程,我们可以把各种费时的操作写在这里面,比如访问网络等。但是,当我们处理完费时操作的时候,可能需要重新绘制界面(访问UI组件),此时我们就需要让工作线程与UI线程交互。经过总结,有以下五种方式

1.Handler机制

2.Activity.runOnUIThread(Runnable)

3.View.Post(Runnable)

4.View.PostDelayed(Runnable,long)

5.AsyncTask

Handler机制

Handler的核心就是处理消息(Message),Handler存在于主线程且一直存在,等待着子线程(工作线程,非UI线程)处理完问题后返回Message,然后由Handler接收,在主线程处理该Message,并调用响应的UI组件,Message就是UI线程与非UI线程之间的交互信息。

说道Handler,就不得不提Looper和MessageQueue,这也是Handler里面不能缺少的两个部分,Looper英文意思就是环,线程通过Looper建立自己的消息循环,MessageQueue是消息队列,采用先进先出存储消息。Looper负责从MessageQueue中取出消息,并分发到指定的Handler对象。

Handler实现代码

UI线程(只能有一个)

private Handler handler = new Handler() {

@Override
public void handleMessage(Message msg) {
// TODO 接收消息并且去更新UI线程上的控件内容
if (msg.what == 0) {
// Bundle b = msg.getData();
// tv.setText(b.getString("num"));
tv.setText(String.valueOf(msg.obj));
}
super.handleMessage(msg);
}
};

非UI线程

new Thread() {
@Override
public void run() {
// TODO 子线程中通过handler发送消息给handler接收,由handler去更新TextView的值
try {
for (int i = 0; i < 100; i++) {
Thread.sleep(500);
Message msg = new Message();
msg.what = 0;
msg.obj = "更新后的值:" + i;
handler.sendMessage(msg);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();


Activity.runOnUIThread(Runnable)

这个可以直接在子线程中写入对UI组件的操作,XActivity.runOnUIThread就能看出,他可以找到对应XActivity的主线程调用UI组件XActivity.currentActivity.runOnUiThread(new Runnable()
{
public void run()
{
Toast.makeText(getApplicationContext(), , "Update My UI",
Toast.LENGTH_LONG).show();
}

});


View.Post(Runnable)

View.PostDelayed(Runnable,long)

待续


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息