和许多其余的GUI 库同样,Android 的UI 也是线程不安全的。也就是说,若是想要更新应用程序里的UI 元素,则必须在主线程中进行,不然就会出现异常。了解AsyncTask的用法,请参见个人博客:(android高级---->Asynctask的源码分析)今天咱们就来学习一下有关UI更新的一些知识。html
目录:java
今天咱们经过一个小案例,来讲明更新UI的所有测试内容:项目结构以下android
在子线程中更新UI
1、 在MainActivity.java的onCreate方法中作一些初始化工做,初始化textView
private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textView); }
2、 点击threadUpdateUI按钮,触发在子线程中更新UI的事件
// 在子线程中更新UI public void threadUpdateUI(View view) { new Thread(new Runnable() { @Override public void run() { textView.setText("I love you."); } }).start(); }
3、 运行结果以下,说明在子线程中的确不能更新UI
- 日志打印结果: Only the original thread that created a view hierarchy can touch its views.
- 测试真机崩溃:
用Handler机制实现UI的更新
1、 定义一个Handler,用于接收处理消息
public static final int UPDATE_TEXT = 1; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case UPDATE_TEXT: textView.setText("I Love you."); break; default: break; } } }
2、 点击按钮,触发在子线程中发送消息的事件
// 用handler处理上述问题 public void handlerUpdate(View view) { new Thread(new Runnable() { @Override public void run() { Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); // 将Message对象发送出去 } }).start(); }
结果正常,textView显示为:I love you安全
用AsyncTask机制实现UI的更新
1、 建立一个继承AsyncTask的内部类,命名为:MyAsynTask
private class MyAsynTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void aVoid) { textView.setText("I love you"); } }
2、 点击按钮,建立AsyncTask的实例,并调用execute方法:
// 用AsyncTask处理上述问题 public void asynTask(View view) { MyAsynTask myAsynTask = new MyAsynTask(); myAsynTask.execute(); }
结果正常,textView显示为:I love you。async
友情连接
关于AsyncTask类的详细使用,请参见个人博客 (android高级---->Asynctask的源码分析)ide