Android 在非主线程无法操作UI意识
Android在应用显示Dialog是一个非常easy事儿,但我从来没有尝试过Service里面展示Dialog。
经验UI操作要在主线程,本地的服务Service是主线程里没错,可是远程service里面显示Dialog,听起来是不是就应该没有在主线程里面了呢?
尝试一下就知道了,写了个AIDL的调用,client端去调用AIDL。在Service这边就是去显示一个Dialog。
AIDL的部分就忽略了。Service这边的代码就和Activity上显示dialog一样。
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("TEST");
builder.setMessage("test");
builder.show();
当然dialog要setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
结果呢,悲剧了。
Can't create handler inside thread that has not called Looper.prepare()
什么意思呢,主观理解,要显示个Dialog须要有消息循环的支持,给它一个消息循环就好了呗。
可是。问题来了。。
。 这个过程发生在哪个线程上呢。后来调试发现原来每次binder调用过来都会有一个线程出现,并且还是每次都是不一样的,预计是从一个线程池里面拿的。
那怎么给这个线程加上looper呢。没办法仅仅能自己开一个线程了。果然在一个带looper的线程里去显示dailog貌似就没问题了。
那么问题又来了,为什么显示Dialog须要looper的支持呢?
看代码:
原来Dialog有一个
private final Handler mHandler = new Handler();
另一个
mListenersHandler = new ListenersHandler(this);
看起来这两个Handler都是长在当前这个线程上的。那就明确了为什么show Dialog一定要looper了吧。
最后另一个问题,一直说UI操作必需要在主线程,那上面说的这个情况就有点奇怪了。显现Service是远程的,显示dialog又是Service的一个子线程,跟主线程有半毛钱关系吗?费解了,以我个人理解。这个非主线程不操作UI看来并非绝对的吧。
再细致想想,之前有看到过,事实上不管是Dialog还是Acitivty本质上都是通过WindowManager往window上加了一个view(ViewRoot),全部的view不可能是仅仅属于一个client。各个client都在这个window上分了一杯羹。那么,有多个线程会去更新各自的view也就不奇怪了。仅仅是每个View本身仅仅能有一个线程来操作罢了。这就是我对非主线程不能操作UI的认识,不知道是不是正确。
版权声明:本文博主原创文章,博客,未经同意不得转载。
Android 在非主线程无法操作UI意识的更多相关文章
- 在非主线程中更新UI
在非主线程中调用了showMessage方法,结果报错:Can't create handler inside thread that has not called Looper.prepare() ...
- 后台子线程(非主线程)更新UI引起的警告
一.问题描述 -(void)sendAsynchronousRequest { NSLog(@"%@",[NSThread currentThread]); [SVProgress ...
- ThreadLocal ——android消息机制handler在非主线程创建not called Looper.prepare() 错误的原因
引用自:https://www.jianshu.com/p/a8fa72e708d3 引出: 使用Handler的时候,其必须要跟一个Looper绑定.在UI线程可直接初始化Handler来使用.但是 ...
- android 4.0主线程訪问网络问题
在4.0下面,在主线程中訪问网络,假设请求超过6s的话,就会报ANR,那么这就会带来一个问题,假设网络慢或者请求的数据过大时,界面会卡顿,造成界面灵敏性非常差,因此网络请求一般不能放在主线程中操作,g ...
- Android中为什么主线程不会因为Looper.loop()方法造成阻塞
很多人都对Handler的机制有所了解,如果不是很熟悉的可以看看我 如果看过源码的人都知道,在处理消息的时候使用了Looper.loop()方法,并且在该方法中进入了一个死循环,同时Looper.lo ...
- 在非主线程里面使用NSTimer创建和取消定时任务
为什么要在非主线程创建NSTimer 将 timer 添加到主线程的Runloop里面本身会增加线程负荷 如果主线程因为某些原因阻塞卡顿了,timer 定时任务触发的时间精度肯定也会受到影响 有些定时 ...
- Android之Handler用法总结/安卓中只有主线程可以修改UI
Handler传递消息的方式可以实现实时刷新以及长按连续响应事件. 按钮响应 btnadd_fcl.setOnTouchListener(new View.OnTouchListener() { pr ...
- 关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?引发的思考,事实可能不是一个 epoll 那么 简单。
( 转载请务必标明出处:http://www.cnblogs.com/linguanh/, 本文出自:[林冠宏(指尖下的幽灵)的博客]) 前序 本文将会把一下三个问题阐述清楚以及一个网上的普遍观点的补 ...
- (转)关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?引发的思考,事实可能不是一个 epoll 那么 简单。
( 转载请务必标明出处:http://www.cnblogs.com/linguanh/, 本文出自:[林冠宏(指尖下的幽灵)的博客]) 前序 本文将会把一下三个问题阐述清楚以及一个网上的普遍观点的补 ...
随机推荐
- hdu3452 无向树去掉最小的边集使不论什么叶子与根不连通 / 最小割
思路一下就上来了,叶子向汇点连边,inf保证不会成为割,跑根到汇点最小割就可以.注意无向树双向建边.基础题,分分钟1A: #include<iostream> #include<qu ...
- MySQL基金会-基本数据库操作
1. 删除数据库 DROP DATABASE 数据库名; mysql> drop database test; 即删除数据库模式 2 .创建数据库 create DATABASE 数据库名; m ...
- [状压dp] hdu 4064 Carcassonne
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4064 Carcassonne Time Limit: 3000/1000 MS (Java/Othe ...
- WindowsPhone 在 根据公历 获取月球日期数据
WindowsPhone 在 根据公历 获取月球日期数据 WindowsPhone 在 它们的定义 类,根据公历 获取月球日期数据 using System; using System.Collect ...
- Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
1.错误叙述性说明 2014-7-10 23:12:23 org.apache.catalina.core.StandardContext filterStart 严重: Exception star ...
- SSH三作品的框架和流程
Hibernate工作的,为什么? 原理: 1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件 2.由hibernate.cfg.xm ...
- Flex强制类型转换错误
1.错误描写叙述 TypeError: Error #1034: 强制转换类型失败:无法将 HoleDetailInnerClass0@c2cccf1 转换为 mx.controls.listClas ...
- Android项目包装apk和apk反编译,xml反编译
一.项目和一般原则其不足之处包 (1)开发一个简单的项目.当发布了APK档.假设我们不使用签名的方式,直接地bin文件夹中找到*.apk档.非常方便,但是,当我们在使用的用户,可能有其他方案覆盖安装. ...
- 对于COM对象使用ComPtr代替传统指针
对于COM对象来说使用传统指针比较麻烦,还要记得Release()防止内存泄漏,一不小心就会出现各种各样的问题.针对这种问题微软提供了对于COM对象的智能指针ComPtr,这里是官方文档https:/ ...
- HDU4866 Shooting (要持久段树)
意甲冠军: 给你一些并行x行轴.总是询问坐标x的顶部之前,k一个段高度,.标题是必须在线. 思路: 首先要会可持久化线段树(又称主席树和函数式线段树).不会的能够去做下POJ 2104. 把全部线段高 ...