主线程中有多个handler的情况
来源:互联网 发布:手机种菜赚钱软件 编辑:程序博客网 时间:2024/05/15 12:37
工作中遇到了这么一种情况,有两个视图,都需要开启异步任务从服务器获取xml数据,每个view中创建一个Handler,注册到异步任务中去,当异步任务从服务器获取数据出错,或者出现io异常或者http协议异常的时候,使用这个handler通知主视图弹出toast通知用户,在同一个activity中根据条件使用不同的视图,这些视图通过一个栈进行管理,加载A后,创建并注册handlerA到taskA,开启异步任务taskA,然后从视图A激活视图B(假定这个时候taskA还没有结束),视图B创建handlerB,注册到异步任务taskB,开启taskB,HandlerA和HandlerB是同一个类的不同实例,taskA请求服务器发生异常,handlerA发送异步消息通知视图A弹出toast通知用户,这个时候视图A处于栈中,没有激活,而视图B处于激活状态,handlerA和handlerB又是同一个类的实例,那么问题来了,HandlerB能够获取HandlerA发送的异步消息吗?过程如下图所示:
handlerB当然不能接收到taskA中的handlerA发送的message,可能有同学会说了,handlerA和handlerB都是在主线程中创建的handler,他们都关联于主线程,每个线程都有一个队列messageQueue,looper管理这个队列并且分发消息,无论是handlerA还是handlerB都是发送消息到主线程中的messageQueue, 并且这两个handler的代码也是一样的,handlerA所在的视图处于后台,视图B在前台,handlerB应该能够接受handlerA发送的消息并且处理啊,测试一下,果然视图b中虽然没有启动taskB,但是依然弹出了toast,难道这种说法是对的吗?
当然不对,主要有这么两个问题。
第一个问题:handlerB能否接收到handlerA发送的消息?
不能,看看Message的创建方式
通过代码我们可以看到Message会指定它的target为发送他的handler
另外一种方式:
这两种创建方式都是一样的。
再来看一下消息是怎么分发的?
Looper会不断的轮询消息队列,将消息发送给响应的handler进行处理
//*****************************************************************************
看上面的红色标注的代码,他会调用这个Message的target的dispatchMessage(msg)分发,上面就说过了这个target就是发送这个消息的handler本身.
至此结束,handlerB根本不会得到handlerA的消息
第二个问题,既然handlerB不能获得handlerA的消息,那么又是如何弹的toast呢?
从上面的代码中我们可以看出来,Toast这种机制是不和view相关的,也不和activity相关的,不像dialog,取决于创建它的activity,Toast是由一种称为INotificationManager的服务管理的,所以虽然视图A虽然没有获取焦点,但是视图A对象仍旧在栈中,handlerA对象也存在,所以当他的到消息的时候,他依旧会去处理,弹出toast,Toast是一种很特别的机制,使用的时候一定要小心。
- 主线程中有多个handler的情况
- 主线程中有多个handler的情况
- 主线程中有多个handler的情况,只会共用一个消息队列(看代码)
- android开发-IntentService的原理(非主线程创建Handler的情况)
- 在主线程的handler里开子线程 主线程会卡主
- 主线程多个Handler 问题
- Android主线程的消息系统(Handler\Looper)
- 在异步线程中使用主线程的handler
- handler 主线程与子线程之间的通信
- androd中主线程和非主线程的通信机制(Handler/Looper/Message)
- ExitThread的用法和主线程调用情况
- handler处理多种情况下的信息处理 handler类讲解
- 主线程、Handler机制原理
- 主线程模型(Handler理解)
- Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别
- Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别
- Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别
- 『ANDROID』Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别
- 递归控件
- 组合、聚合和关联的关系
- linux 设置服务随系统启动
- 如何成为一位杰出的工程师
- linux下文件权限的操作
- 主线程中有多个handler的情况
- 债券研究系列之三——债券指数
- linux下头文件概述(不定期更新)
- DB2大数据处理不记录日志
- 【转】苹果电脑到底支持哪些常用软件
- php简单语句测试,居然是if最快
- 自己如何正确获取SQLite的ADO连接字符串
- 【转】MAC常用的127个常用软件
- 天气不错