【转】 android 那些事---主线程是线程不安全的

转自:http://blog.csdn.net/dxpqxb/article/details/7987764

我们经常看见一句话:Android主线程是线程不安全的。这句话的意思是:更新UI只能是主线程的工作,子线程更新UI是线程不安全的,所以android里非主线程操作主UI就会报错。为什么呢?因为子线程可能会有多个,多个线程同时操作一个控件可能会有冲突发生,所以android就限定了只有主线程可以操作UI。子线程想操作UI,可以,你告诉我(主线程),我来更新。

在一个Android 程序开始运行的时候,会单独启动一个进程Process。默认的情况下,所有这个程序中的Activity或者Service(Service和Activity只是Android提供的Components中的两种,除此之外还有Content Provider和Broadcast Receiver)都会跑在这个进程空间里。

一个Android 程序默认情况下也只有一个进程Process,但可以有许多个线程Thread。

在这么多Thread当中,有一个Thread,我们称之为UI Thread。UI Thread在Android程序运行的时候就被创建,是一个Process当中的主线程Main Thread,主要是负责控制UI界面的显示、更新和控件交互。在Android程序创建之初,一个Process呈现的是单线程模型,所有的任务都在一个线程中运行。因此,我们认为,UI Thread所执行的每一个函数,所花费的时间都应该是越短越好。而其他比较费时的工作(访问网络,下载数据,查询数据库等),都应该交由子线程去执行,以免阻塞主线程。(如果主线程被阻塞5秒,就会弹出应用程序没有响应,是等待还是关闭的警告。)


那么,UI Thread如何和其他Thread一起工作呢?常用方法是:

新建一个主线程的Handler实例,当做Listener去让子线程能将数据Push到主线程的Message Quene里,以便触发主线程的handlerMessage()函数,让主线程知道子线程的状态,并在主线程更新UI。


例如,在子线程的状态发生变化时,我们需要更新UI。如果在子线程中直接更新UI,通常会抛出下面的异常:

ERROR/JavaBinder(1029):android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.

意思是,无法在子线程中更新UI。为此,我们需要通过Handler实例,通知主线程Ui Thread来更新界面。

如下,首先在主线程创建一个Handler,来监听Message的事件:

private final int UPDATE_UI = 1;
private Handler mHandler = new MainHandler();

private class MainHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_UI: {
Log.i("TTSDeamon", "UPDATE_UI");
showTextView.setText(editText.getText().toString());
ShowAnimation();
break;
}
default:
break;
}
}
}

或者

private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_UI: {
Log.i("TTSDeamon", "UPDATE_UI");
showTextView.setText(editText.getText().toString());
ShowAnimation();
break;
}
default:
break;
}
}
}


当子线程的状态发生变化,则在子线程中发出Message,通知主线程更新UI。

mHandler.sendEmptyMessageDelayed(UPDATE_UI, 0);

更多相关文章

  1. android studio 不能在线更新android SDK Manager问题解决办法
  2. 2011.06.21(2)——— android invalidate和postInvalidate
  3. android:launchMode="singleTask" intent获取到的值没有更新
  4. 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
  5. Android笔记--handler机制
  6. 用 SDK Manager.exe 无法更新 Android(安卓)SDK Tools 的解决办
  7. Android之Handler用法总结
  8. Android之Handler用法总结
  9. Android之Handler用法总结

随机推荐

  1. android 获取外置sd卡根目录
  2. 运行时权限解析以及申请的实现(可完美解决
  3. Android教程之MediaStore
  4. Android(安卓)操作软键盘
  5. android WebView加载html5介绍
  6. Android中的style和theme的用法
  7. Android实现页面悬浮显示
  8. Android(安卓)的res/values/colors自定义
  9. 深入浅出RxJava四-在Android中使用响应式
  10. ArcGIS for Android安装配置详解