Android开发——子线程操作UI的几种方法
在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法:
转载请标明出处:http://blog.csdn.net/seu_calvin/article/details/52120389
方法1 Activity.runOnUiThread
方法如下:
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText("Hello");
}
});
这种方法简单易用,如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,就发布到事件队列的UI线程。其实和Handler差不多,都是将这个更新UI的请求消息,加入到事件队列,等待主线程空闲的时候执行。
方法2 Handler
主线程中定义Handler如下:
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
String data = (String)msg.obj;
textView.setText(data);
break;
default:
break;
}
}
};
子线程发消息,通知Handler完成UI更新,代码如下:
new Thread(new Runnable(){
@Override
public void run() {
//耗时操作
mHandler.sendEmptyMessage(0);
Message msg =new Message();
msg.obj = "数据";//可以是基本类型,可以是对象,可以是List、map等
mHandler.sendMessage(msg);
}
}).start();
方法3 View.post
final Button btn =(Button)findViewById(R.id.btn);
btn.post(new Runnable(){
@Override
publicvoid run() {
btn.setText("Hello");
}
});
上面的代码就是更新btn中的内容,同样下面的代码也可以达到这种效果。
Handler handler = new Handler();
final Button btn = (Button)findViewById(R.id.btn);
handler.post(new Runnable(){
@Override
public void run() {
btn.setText("Hello");
}
});
这个是用handler.post方法,一个是用View.post方法,handler.post方法已经在Android的消息机制中介绍过了,其实最终也是调用了方法2中的send方法。
现在看一下View.post方法的源代码:
public boolean post(Runnable action) {
Handler handler;
AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
handler = attachInfo.mHandler;
} else {
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
return handler.post(action);
}
方法中主要的功能代码就是attachInfo.mHandler,获取当前线程(即UI线程)的Hanlder,然后将action对象post到Handler里。在Handler里的处理过程上面链接文已经分析的很清楚了,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。在Handler的dispatchMessage方法里,第一句话就是为它所设,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。
方法4 广播
子线程中发送广播,主线程中接收广播并更新UI。
方法5 使用AsyncTask
为了简化子线程中访问UI,系统提供给了我们AsyncTask。
AsyncTask是一种轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行进度和结果传递给主线程并更新UI。本质上来说AsyncTask封装了Thread和Handler,但是AsyncTask不适合进行特别耗时的后台任务,如果需要进行特别耗时的任务,建议使用线程池。
不同API版本的AsyncTask具有不同的表现,因此需要注意。为了控制篇幅,具体的AsyncTask的使用方法和工作原理,写在这篇文章,AsyncTask的使用以及源码解析,有兴趣的同学可以查看。
Android开发——子线程操作UI的几种方法的更多相关文章
- Android开发——子线程操作UI的几种方法(待续)
方法2 Handler andler mHandler = new Handler() { @Override public void handleMessage(Message msg) { su ...
- Android通过子线程更新UI的几种方式
一般情况下,UI的更新都少不了Handler,首先我们先了解一下Handler机制: Handler消息机制 定义 Message 线程间通信的数据单元,可通过message携带需要的数据创建对象:M ...
- iOS子线程更新UI的两种方法
http://blog.csdn.net/libaineu2004/article/details/45368427 方法1:performSelectorOnMainThread[self perf ...
- iOS子线程操作UI问题检查
iOS开发中,因为大部分函数都不是线程安全的,所以UI子线程中操作UI是非常危险的事,但是有时候因为开发者经验不足,不知道子线程中不能UI,或者知道但是写代码的时候没注意,或者不知道那些函数操作UI了 ...
- Android可以子线程更新UI?
初了解Android的时候,就知道Android是不能在子线程更新UI的,不然程序会直接抛出异常,告诉你,别给我在自线程搞事情! 但是,这个是针对普通的view做的限制,而TextureView,Su ...
- android 解决子线程进行UI操作
Android确实不允许在子线程中进行UI操作的,但我们有时必须在子线程里去执行一些耗时的任务,然后根据任务的执行结果来更新相应的UI控件. Android提供了一套异步消息处理机制,可以解决子线程中 ...
- android基础---->子线程更新UI
和许多其他的GUI 库一样,Android 的UI 也是线程不安全的.也就是说,如果想要更新应用程序里的UI 元素,则必须在主线程中进行,否则就会出现异常.了解AsyncTask的用法,请参见我的博客 ...
- C#子线程更新UI控件的方法总结
http://blog.csdn.net/jqncc/article/details/16342121 在winform C/S程序中经常会在子线程中更新控件的情况,桌面程序UI线程是主线程,当试图从 ...
- 解决子线程操作UI的方法
随机推荐
- 洛谷P3603 || bzoj 4763 雪辉 && bzoj4812: [Ynoi2017]由乃打扑克
https://www.luogu.org/problemnew/show/P3603 https://www.lydsy.com/JudgeOnline/problem.php?id=4763 就是 ...
- Java EE学习笔记(五)
Spring事务管理 1.Spring事务管理概述 1).在实际开发中,操作数据库时都会涉及到事务管理问题,为此Spring提供了专门用于事务处理的API.(事务特性:ACID,原子性,一致性,隔离性 ...
- git(代码仓库)
第1章 git介绍 1.1 参数: 第2章 git管理一个项目 2.1 图示 2.2 cd /项目路径 2.3 git config --globle user.email "邮箱地址&q ...
- jdk1.8源码包下载并导入到开发环境下助推高质量代码(Eclipse、MyEclipse和Scala IDEA for Eclipse皆适用)(图文详解)
不多说,直接上干货! jdk1.8 源码, Linux的同学可以用的上. 由于源码JDK是前版本的超集, 所以1.4, 1.5, 1.6, 1.7都可以用的上. 其实大家安装的jdk路径下,这 ...
- javascript 转化一个数字数组为function数组(每个function都弹出相应的数字)
javascript 转化一个数字数组为function数组(每个function都弹出相应的数字) var arrNum = [2,3,4,5,6,10,7]; var arrFun = []; f ...
- AJPFX简述i=i+1与i+=1及x++的区别和效率
i=i+1与i+=1及x++的区别和效率 1.x=x+1,x+=1及x++的效率哪个最高?为什么? x=x+1最低,因为它的执行如下. (1)读取右x的地址: (2)x+1: (3)读取左x的地址: ...
- apache关联php
LoadModule php5_module "D:/softs/php/php5apache2_2.dll" AddType application/x-httpd-php .p ...
- rpm包的安装方法
每次都记不住,这次必须整理一下!cd到你存放rpm文件包的目录rpm -ivh linuxqq-v1.0.2-beta1.i386.rpm安装时可能会遇到缺少包的错误.rpm -ivh --repla ...
- Android adb命令,linux中各种命令
常用的ADB命令 1. 显示系统中全部Android平台: android list targets 2. 显示系统中全部AVD(模拟器): android list avd 3. 创建AVD(模拟器 ...
- IOS7适配
(1)如果应用程序始终隐藏 status bar 那么恭喜呢,你在UI上需要的改动很少很少. (2)如果应用程序显示status bar,可以讲status bar设置成黑色不透明 ,然后在UIVie ...