使用Thread+Handler实现非UI线程更新UI界面
来源:互联网 发布:安卓登录注册界面源码 编辑:程序博客网 时间:2024/05/16 07:01
概述:每个Android应用程序都运行在一个dalvik虚拟机进程中,进程开始的时候会启动一个主线程(MainThread),主线程负责处理和ui相关的事件,因此主线程通常又叫UI线程。
而由于Android采用UI单线程模型,所以只能在主线程中对UI元素进行操作。
如果在非UI线程直接对UI进行了操作,则会报错:
CalledFromWrongThreadException:only the original thread that created a view hierarchy can touch its views
Android为我们提供了消息循环的机制,我们可以利用这个机制来实现线程间的通信。那么,我们就可以在非UI线程发送消息到UI线程,最终让UI线程来进行UI的操作。
对于运算量较大的操作和IO操作,我们需要新开线程来处理这些繁重的工作,以免阻塞ui线程。
例子:下面我们以获取CSDN logo的例子,演示如何使用Thread+Handler的方式实现在非UI线程发送消息通知UI线程更新界面。
- public class ThreadHandlerActivity extends Activity {
- /** Called when the activity is first created. */
- private static final int MSG_SUCCESS = 0; //获取图片成功的标识
- private static final int MSG_FAILURE = 1; //获取图片失败的标识
- private ImageView mImageView;
- private Button mButton;
- private Thread mThread;
-
- //handleMessage()此方法是主线程用来处理发送给它的消息
- private Handler mHandler = new Handler() {
- public void handleMessage (Message msg) {//此方法在ui线程运行
- //判断msg.what的值可以知道mThread是否成功获取图片
- switch(msg.what) {
- case MSG_SUCCESS:
- mImageView.setImageBitmap((Bitmap) msg.obj); // msg.obj获取对象,完成UI的更新操作
- Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_success), Toast.LENGTH_LONG).show();
- break;
- case MSG_FAILURE:
- Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_failure), Toast.LENGTH_LONG).show();
- break;
- }
- }
- };
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mImageView= (ImageView) findViewById(R.id.imageView); //显示图片的ImageView
- mButton = (Button) findViewById(R.id.button);
- mButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if(mThread == null) {
- mThread = new Thread(runnable);
- mThread.start(); //线程启动
- }
- else {
- Toast.makeText(getApplication(), getApplication().getString(R.string.thread_started), Toast.LENGTH_LONG).show();
- }
- }
- });
- }
- Runnable runnable = new Runnable() {
- @Override
- public void run() { //run()在新的线程中运行
- HttpClient hc = new DefaultHttpClient();
- HttpGet hg = new HttpGet("http://csdnimg.cn/www/images/csdnindex_logo.gif"); //获取csdn的logo
- final Bitmap bm;
- try {
- HttpResponse hr = hc.execute(hg);
- bm = BitmapFactory.decodeStream(hr.getEntity().getContent());
- } catch (Exception e) {
- mHandler.obtainMessage(MSG_FAILURE).sendToTarget(); //获取图片失败
- return;
- }
- //obtainMessage()发送消息到UI线程的消息队列
- mHandler.obtainMessage(MSG_SUCCESS,bm).sendToTarget(); //获取图片成功,向ui线程发送MSG_SUCCESS标识和bitmap对象
- // mImageView.setImageBitmap(bm); // 出错!不能在非ui线程操作ui元素
-
- // 子线程通过post将Runnable加入到主线程的messagequeue中,主线程调用runnable的方法,相当于在主线程中更新UI,执行mImageView.setImageBitmap(bm);
- // mImageView.post(new Runnable() { //另外一种更简洁的发送消息给ui线程的方法。
- //
- // @Override
- // public void run() {//run()方法会在ui线程执行
- // mImageView.setImageBitmap(bm);
- // }
- // });
- }
- };
- }
0 0
- 使用Thread+Handler实现非UI线程更新UI界面
- 使用Thread+Handler实现非UI线程更新UI界面
- 使用Thread+Handler实现非UI线程更新UI界面
- 使用Thread+Handler实现非UI线程更新UI界面
- 使用Thread+Handler实现非UI线程更新UI界面
- Android使用Thread+Handler实现非UI线程更新界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 .
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 .
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- UVa 11059 最大乘积(枚举)
- ThinkPHP的RBAC权限控制
- apk反编译详解
- 翻转单链表
- Implement Stack using Queues
- 使用Thread+Handler实现非UI线程更新UI界面
- echarts 图表 展示 练习二 (ajax 后台加载数据)
- JDK各个版本的新特性jdk1.5-jdk8
- 配置环境变量 解决tomcat启动闪退现象
- sql联合查询inner join
- css样式学习
- 如何在Android开发中使用自定义的字体库
- Num 22 : NYOJ : 0055 懒省事的小明 [ 优先队列 ]
- jquery全选