`
zhuyifeng
  • 浏览: 44063 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

android子线程不能更新主线程创建的组件解决方法

阅读更多



         一般来说我们在开发android时,都会把一些耗时比较长的任务放在子线程中运行以免卡住主线程从而造成比较差的用户体验,比如说从网络上下载文件一般就要放入子线程中来处理,而一般下载的时候都会有一个progress bar进度条来动态显示下载进度,但是我们知道在android里面不是线程安全的,所以android有阻止子线程更新组件的机制。如果强制运行,就会报android.view.ViewRootImpl$CalledFromWrongThreadException,本文以网络聊天为例(侦听另一方发过来的流数据,肯定得用子线程来嘛O(∩_∩)O~~)

      先贴一段代码:意思很简单,就是一直在监听,当收到消息的时候更新组件textView

new Thread() {
				public void run() {
					while (true) {
						try {
							String s = dis.readUTF();
							textView.setText(s);
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}.start();

 

      很显然,这样会报错,图片如下:

 

      那么我们该怎么解决呢?android给我们提供了一种消息处理机制,即handler,用来处理不同线程之间的消息。每个线程都有属于自己的一个handler,可以直接通过new方法得到,而在子线程中,我们可以把接收到的信息封装在一个Message对象里面,并调用主线程中的handler对象的sendMessage(Message msg)方法,将该Message对象传递过去,然后主线程的handler收到Message后就会自动调用handleMessage(Message msg)方法,我们就可以通过重写该方法(在主线程中完成)来实现我们想要的操作了。

 

      主线程中的代码:

	// 获取handler对象,该对象为全局变量
		handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				// 获取封装在Message对象中的信息
				String s = (String) msg.obj;
				// 在主线程中对组件进行操作
				textView.append("对方:" + s + '\n');
			}
		};

 

      子线程中的代码:

new Thread() {
				public void run() {
					while (true) {
						try {
							// 从网络流中读取字符串
							String s = dis.readUTF();
							// 创建Message对象
							Message message = Message.obtain();
							// 封装数据
							message.obj = s;
							handler.sendMessage(message);
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}.start();

 

  • 大小: 60.5 KB
分享到:
评论

相关推荐

    android 服务组件多线程交互

    android 的service和activity是运行在UI主线程的。在android线程中,只有主线程即UI线程有自己的默认的消息队列。子线程需要创建自己的消息队列,并把消息发给队列,并循环起来,发给handler处理。

    《Android系统源代码情景分析》

    15.1 应用程序主线程消息循环模型 15.2 与界面无关的应用程序子线程消息循环模型 15.3 与界面相关的应用程序子线程消息循环模型 第16章 Android应用程序的安装和显示过程 16.1 应用程序的安装过程 16.2 ...

    浅谈Android 的线程和线程池的使用

    Android 中主线程交 UI 线程,主要作用是运行四大组件以及处理它们和用户的交互;子线程的作业则是执行耗时任务。 Android 中的线程形态 1、AsyncTask AsyncTask 是一种轻量级的异步任务类,可以在线程池中执行后台...

    Android系统源代码情景分析-罗升阳-源码

    15.1 应用程序主线程消息循环模型 15.2 与界面无关的应用程序子线程消息循环模型 15.3 与界面相关的应用程序子线程消息循环模型 第16章 Android应用程序的安装和显示过程 16.1 应用程序的安装过程 16.2 应用...

    Android代码-login

    一:进入需要登录后的页面(显然只支持主线程)。二:需要登录后操作的功能如点赞,弹出漂亮对话框等(支持多线程)。 第一种在相应界面的activity上加CheckIfLoginAndLoginAndBackToContinue注解即可实现该界面任何...

    android学习笔记之handler消息处理机制1

    在android中有一个规则:考虑到安全性,子线程不能动态的改变主线程中组件的属性值。 但为了执行一些耗时操作,往往会将它们放在子线程中,执行完毕要更新主线程中的UI,所以就有了handler消息处理机制。 handler就...

    Android中Handler消息传递机制

    在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息。当你创建子线程时,你可以在你的子线程中拿到父线程中创建的Handler 对象,就可以通过该对象向父线程的消息队列发送消息了。...

    Android.zip

    子线程UI: 快速定位哪一些 UI 操作在非主线程中进行渲染,避免不必要的问题; 清除本地数据: 一键删除沙盒中所有数据; NSLog: 把所有 NSLog 信息打印到UI界面,避免没有开发证书无法调式的尴尬; Lumberjack...

    android 面试2

    避免ANR:Android应用程序通常运行在一个单独的线程里面,称谓主线程,所以在主线程里面少做一些耗时长的程序,而是利用子线程来操作一些繁琐的事情,用Handler来把子线程处理的消息返回给主线程 22、简要解释一下...

    Android系统源代码情景分析光盘

    Android系统源代码情景分析光盘资料 目录 第1篇初识Android系统 第1章 准备知识................................................................ 2 1.1 Linux内核参考书籍......................................

    DoraemonKit研发助手-其他

    8、【子线程UI】 快速定位哪一些 UI 操作在非主线程中进行渲染,避免不必要的问题;(iOS独有)9、【清除本地数据】 一键删除沙盒中所有数据;10、【NSLog】 把所有 NSLog 信息打印到UI界面,避免没有开发证书无法...

Global site tag (gtag.js) - Google Analytics