Android中更新UI的四种方式
前言
当我们在对ui做出更改时,Android检查我们当前的操作线程是否为UI线程,若不是即报出异常。
那么我们该如何更新Ui呢,这里简要使用和讲述的是Handler。先简述概念:Adroid在运行时会创建一个UiThread的主线程来负责控制UI界面的显示、更新和控件交互。其他线程则通过handler将更新逻辑等消息事件(Message) push到主线程的消息队列(MessageQueue),最后由主线程有序地处理这些消息事件(handleMessage),实现对界面的更新和控制。
常用的方法总结
- Handler.sendMessage();
- AsyncTask方法;
- runOnUiThread();
- Handler.post();
Handler的机制讲解
Handler原理
Handler
封装发送消息。
Looper
内部包含一个消息队列MessageQueue,所有的Handler发送的消息都回到这个队列,遵循先进先出。
Looper.loop()方法是一个死循环,不断地从MessageQueue中获取消息,如果有消息就回立刻处理消息,不会造成消息的阻塞。
MessageQueue是一个消息列队,可以添加和处理消息。
总结:Handler负责发送消息;Looper负责读取Handler发送给MessageQueue的消息,并将消息发送给相应的Handler;MessageQueue负责存储消息。且多个线程中只有一个Looper和Message Queue。
1. handler.sendMessage()方法
public class MainActivity extends Activity {
/**定义显示控件**/
private TextView tv;
/**创建个新Handler**/
Handler handler = new Handler()
{
public void handleMessage(Message msg) {
//判断消息
if(msg.what==0x111)
{
tv.setText("更新后的TextView");
}else{
// TODO: 其他消息
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
new MyThread().start();
}
class MyThread extends Thread
{
@Override
public void run() {
try {
//延时1000ms
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//发送一个指定类型what的空消息0x111
handler.sendEmptyMessage(0x111);
}
}
}
2. AsyncTask方法
public class MainActivity extends Activity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
new Yibu().execute();
}
class Yibu extends AsyncTask<String, String, String>
{
@Override
protected String doInBackground(String... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
tv.setText("更新后的TextView");
}
}
}
3. runOnUiThread()方法
public class MainActivity extends Activity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
new MyThread().start();
}
class MyThread extends Thread
{
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
//延迟一秒更新
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
tv.setText("更新后的TextView");
}
});
}
}
}
4.Handler. Post()方法
public class MainActivity extends Activity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
Handler handler = new Handler();
handler.post(new Runnable(){
@Override
public void run() {
try {
//延迟一秒更新
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
tv.setText("更新后的TextView");
}