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

Android 中更新 UI 的几种方式

2017-01-06 15:07 375 查看
Android有4种更新UI的方式分别是:

runOnUiThread
handler 的 post
handler 的 sendMessage
View 自身的 post
本文只介绍 handler的sengMessage和runOnUiThread这两种方式

Handler 是 Android 给我们提供来更新 UI 的一套机制,也是一套消息处理的机制,我们可以发送消息,也可以通过它来处理消息,Handler 在我们的 framework 中是非常常见的。
Android 在设计的时候,就封装了一套消息创建、传递、处理机制,如果不遵循这样的机制就没有办法更新 UI 信息,就会抛出异常信息。


 Android 为什么要设计只能通过 Handler 机制更新 UI 呢?

最根本的目的就是解决多线程并发的问题,假设在一个 Activity 当中,有多个线程去更新 UI,并且对更新的 UI 的操作进行枷锁处理的话又会产生什么样的问题呢? 那就是性能下降,Handler 通过消息队列,保证了消息处理的先后有序。

注意:在安卓的世界里面,当 子线程 在执行耗时操作的时候,不是说你的主线程就阻塞在那里等待子线程的完成——也不是调用 Thread.wait()或是Thread.sleep()。安卓采取的方法是,主线程应该为子线程提供一个Handler,以便完成时能够提交给主线程。以这种方式设计你的应用程序,将能保证你的主线程保持对输入的响应性并能避免由于5秒输入事件的超时引发的ANR对话框。为了避免ANR,我们会通常把
耗时操作放在子线程里面去执行,因为子线程不能更新UI,所以当子线程需要更新的UI的时候就需要借助到安卓的消息机制,也就是Handler机制了


Handler 的原理是什么?

Handler 封装了消息的发送(主要包括消息发送给谁) Looper:
内部包含一个消息队列也就是 MessageQueue,所有 Handler 发送的消息都走向这个队列。
Looper.loop()方法,就是一个 for 死循环,不断的从 MessageQueue 取消息,如果有消息就处理消息,没有消息就阻塞。

MessageQueue,就是一个消息队列,可以添加消息,处理消息。
Handler 也不难,比较简单,在构造 Handler 时候内部会跟 Looper 进行关联,通过 Looper.myLooper() 获取到 Looper,找到 Looper 也就找到了 MessageQueue。在 Handler 中发送消息,其实是向 MessageQueue 队列中发送消息。

Message
 消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
Message Queue
 消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
Handler
 Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
Looper
 循环器,扮演Message
Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
线程
 UI thread 通常就是main
thread,而Android启动程序时会替它建立一个Message Queue。每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息

通过一个例子:
主要步骤是这样子的:
1、new出来一个Handler对象,复写handleMessage方法
2、在需要执行更新UI的地方 sendEmptyMessage 或者 sendMessage
3、在handleMessage里面的switch里面case不同的常量执行相关操作

final TextView tv11 = (TextView) findViewById(R.id.tv11);

final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:

//这里进行UI操作
tv11.setText("你好");
break;
}
}
};
tv11.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);//把消息发送出去
}
}).start();
}
});
}

相对于handler来说runOnUiThread就比较简单了 

final TextView tv11 = (TextView) findViewById(R.id.tv11);
tv11.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

runOnUiThread(new Runnable() {
@Override
public void run() {
tv11.setText("你好");                    }
});
}
});
}

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