众所周知,在非主线程中更新UI会发生ANR,所以通常使用handler。
创建一个Handler类的实例,在这个Handler实例的handleMessage回调函数中调用更新界面显示的函数。
还有一种封装好的方法:runOnUiThread:点击按钮,更新UI。
把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给runOnUiThread(Runnable)。 这样Runnable对像就能在ui线程中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程。
创建一个Handler类的实例,在这个Handler实例的handleMessage回调函数中调用更新界面显示的函数。
还有一种封装好的方法:runOnUiThread:点击按钮,更新UI。
把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给runOnUiThread(Runnable)。 这样Runnable对像就能在ui线程中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程。
其实和handler差不多,都是将这个更新UI的请求消息,加入到事件队列,等待主线程空闲的时候执行。
package code.xzy.com.updateuidemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
/**
* 测试更新UI的两种方式
* 1.Handler:mHandler通过调用sendMessage()分发消息,交给handleMessage()处理
* 2.runOnUiThread:
* 把更新ui的代码创建在Runnable中,然后在需要更新ui时,
* 把这个Runnable对象传给runOnUiThread(Runnable)。
* 这样Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,
* 那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程。
*/
public class MainActivity extends Activity {
private TextView mTextView;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
mTextView.setText("update UI by handler.");
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.info_tv);
findViewById(R.id.update_text_by_handler).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
mHandler.sendEmptyMessage(1);
}
}).start();
}
});
findViewById(R.id.update_text_by_runOnUiThread).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
//模拟耗时操作
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//更新UI的代码
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText("update UI by runOnUiThread.");
}
});
}
}).start();
}
});
}
}
补充:Andriod如何处理UI与耗时操作的通信,有哪些方式及各自的优缺点
主要有三种方法:
1.Handler
handler机制是,在主线程中创建handler对象, 当执行耗时操作时,新建一个线程,在这个线程中执行耗时操作,通过调用handler的sendMessage,post等方法,更新ui界面;
2.AsyncTask
AsyncTask本质上是一个线程池,所有的异步任务都会在这个线程池中的工作线程中执行,当需要操作ui界面时,会和工作线程通过handler传递消息;
3.自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui;
自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui,这种方法需要把context对象强制转换成activity后使用
各自优缺点:
Handler机制的优点是 结构清晰,功能明确,但是代码过多;
AsyncTask简单,快捷,但是可能会新开大量线程,消耗系统资源,造成FC;
runOnUiThread()方法最好用,代码也非常简单,只是需要传递context对象.