Android UI 操作是线程不安全的。我们只能在UI线程或者说主线程中修改UI。试想多个Thread操作同一个UI,可能引起不一致。UI 线程的主要工作是:UI界面更新显示,各个控件的交互等等。一些耗时(time-consuming)操作不能放在UI线程中,典型的如:查询数据库,网络请求等等。这些操作留给worker线程来做。如何将worker线程的工作结果显示在UI上呢,

Android 提供的解决方法:提供Handler,用于thread之间的通信。通过Handler发送Message或者Runnable到MessageQueen。这其中有许多概念。这些概念是理解Android Thread 的关键。

一、实现 worker Thread修改UI。

  worker Thread 是相对主线程Main Thread(UI thread)来说的。

以简单的实例说明:点击按钮屏幕Toast提示,更新button 文字。

  1.通过handler 向 MessageQueen中发送Message。在Handler 的回调函数 handlerMessage() 中完成UI的更新。

  

public class MainActivity extends Activity {

	private Handler mHandler;
private Button mButton ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button)findViewById(R.id.btn);
mHandler = new Handler(){
@Override
public void handleMessage(Message msg){
updateUI();
};
}; mButton.setOnClickListener(new OnClickListener(){ @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new Thread(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
TimeConsumeTask();
mHandler.sendEmptyMessage(0);
} }).start();
} });
}

  // 更新UI操作
public void updateUI(){
Toast.makeText(getApplicationContext(), "更新UI", Toast.LENGTH_LONG).show();
mButton.setText("UI update");
}

  // 模拟耗时操作
public void TimeConsumeTask(){
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

  mHandler 为Activity 的成员变量,handleMessage函数中的更新UI操作是在UI线程中完成的。

显示:

  

  2.通过handler 向 MessageQueen中Post Runnable 对象,Runnable对象中执行的是UI更新操作。

将上面上的代码稍作改动:

public class MainActivity extends Activity {

	private Handler mHandler;
private Button mButton ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button)findViewById(R.id.btn);
// mHandler = new Handler(){
// @Override
// public void handleMessage(Message msg){
// updateUI();
// };
// };
mHandler = new Handler(); mButton.setOnClickListener(new OnClickListener(){ @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new Thread(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
TimeConsumeTask();
//mHandler.sendEmptyMessage(0);
mHandler.post(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
updateUI();
} });
} }).start();
} });
} public void updateUI(){
Toast.makeText(getApplicationContext(), "更新UI", Toast.LENGTH_LONG).show();
mButton.setText("UI update");
} public void TimeConsumeTask(){
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

  运行结果是一样的。

  mHandler post Runnable对象到了UI thread 的MessageQueen中,UI thread的 Looper 负责处理MessageQueen中的message,Runnable中的更新UI代码最终是在UI thread中执行的。

最新文章

  1. 两listview联动
  2. docker 实践笔记
  3. Electron-使用Electron开发第一个应用
  4. Ansible-Tower快速入门-3.快速开始【翻译】
  5. Android图片异步加载框架Android-Universal-Image-Loader
  6. Python学习笔记12—类
  7. 安装win7 32位系统出现的问题解决办法
  8. mac中viso的兼容工具
  9. js 判断数组中是否存在
  10. Laravel 模板引擎Blade中标签详细介绍
  11. JavaScript之转义字符
  12. IIS架构与HTTP请求处理流程
  13. arcgis jsapi 调用google地区服务
  14. Unity插件之NGUI学习(6)—— 关于Widget怎样加入触发事件(触发OnClick)
  15. 0基础搭建Hadoop大数据处理-环境
  16. android网页分享到朋友圈问题求助?
  17. multisim&proteus&protel比较
  18. JAVA基础-IO流(一)
  19. cocos2d-js(一)引擎的工作原理和文件的调用顺序
  20. Spring Boot 入门(六):集成 treetable 和 zTree 实现树形图

热门文章

  1. nodejs之util工具
  2. HTTP Header User-Agent的ctf
  3. 突破MIME限制上传
  4. PHP之文件大小的转换函数
  5. CSS布局奇淫技巧之--各种居中<转>
  6. Am335x 应用层之SPI操作
  7. 条件随机场(Conditional random field,CRF)
  8. boost 互斥体和锁
  9. Java分为三个体系
  10. HashSet非常的消耗空间,TreeSet因为有排序功能,因此资源消耗非常的高,我们应该尽量少使用