正确处理Ordered Broadcasts
原文:http://aoandroid.com/node/1414
最近,Android官方开发员博客(Developers Blog)登载了Google巴西分布的一名工程师(
Belo Horizonte )的文章,介绍了正确使用Broadcast的概念和实例分析。该文章在概念上纠正了很多开发人员对Broadcast处理中存在的严重问题,并指出这反映了开发文档存在缺陷,没有解释清楚。
Broadcast是Android的一个很有用的概念。当系统产生某些事件的时候,apps可以对某些事件(ACTION)注册(register)后,通过BroadcastReceiver捕捉到这些Broadcasts,从而获得一些很重要的系统信息。电池状态就是一个例子,比如,ACTION_BATTERY_LOW。
Belo注意到有些开发人员没有使用正确方法调用BroadcastReveiver。比较有代表性的概念混淆是
Not ordered 相对于 Ordered Broadcasts
在Not-ordered模式,系统的Broadcasts是同时发布出来,所有receiver都可以得到该事件信息,互相并不影响。即,一个receiver不能影响其它receivers是否能获得该事件信息。上面电池的 ACTION_BATTERY_LOW 就是属于not-ordered事件。
在ordered模式,broadcasts是通过优先设置传达给不同receivers的,优先度在AndroidManifest文件中通过android:priority的intent-filter设置控制的。某个receiver可以通过BroadcastReceiver取消broadcast,取消后,比它优先度底的receivers将不再能得到该broadcast。一个典型的例子是,ACTION_NEW_OUTGOING_CALL。
每当用户拨打电话的时候,系统会发布(broadcast)这个 ACTION_NEW_OUTGOING_CALL 的事件。由于这是个ordered broadcast,app的不同receiver可以对它进行必要的控制。Belo给出一段暗含问题的代码
(注意,CallReceiver 必须首先在AndroidManifest里面关联ACTION_NEW_OUTGOING_CALL)
public class CallReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Original phone number is in the EXTRA_PHONE_NUMBER Intent extra. String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); if (shouldCancel(phoneNumber)) { // Cancel our call. setResultData(null); } else { // Use rewritten number as the result data. setResultData(reformatNumber(phoneNumber)); } }
这段代码试图在获得
ACTION_NEW_OUTGOING_CALL后根据条件,或者拒绝拨打电话,或者让用户修改电话号码。
但是,只有在没有其它具备更高优先度的Receiver的时候,这段代码才会如预期的正确执行。如果有一个更高优先的receiver也关联了ACTION_NEW_OUTGOING_CALL,并且先于这段代码执行了,那么,有可能他们会用一样的原始号码,而没有正确的使用修改后的号码。
正确的做法应该是如下列代码那样:
public class CallReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Try to read the phone number from previous receivers. String phoneNumber = getResultData(); if (phoneNumber == null) { // We could not find any previous data. Use the original phone number in this case. phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); } if (shouldCancel(phoneNumber)) { // Cancel our call. setResultData(null); } else { // Use rewritten number as the result data. setResultData(reformatNumber(phoneNumber)); } }
这段代码事先判断了是否有另外receiver可能已经生成了一个拨号号码,没有的话,才调用intent extra的
EXTRA_PHONE_NUMBER。
这个问题有多严重?
Belo声称,很多apps被发现,使用priority 0的NEW_OUTGOING_CALL的receivers,所有这些receivers都如上述第一个代码例子那样忽略了可能的高优先receivers已经先期执行,并同样关联了NEW_OUTGOING_CALL。当然,你也可以把所有关联了NEW_OUTGOING_CALL的receivers都设在priority 0上,但是这又违反了Android拨打电话的代码处理原则,如果不能访问这个链接,可以参考SDK带的文档。
该处理原则是:
‘为了保持一致性,任何意在阻止向外拨打电话的receiver必须设0优先 (priority 0),以确保该receiver获得最后输入的电话号码。任何意在修改拨打号码的receiver应该设正数优先度,即大于零的正数。负数优先度是给系统保留的,任何apps用负数优先度可能引发问题’
Belo的结论是,很多应用软件存在这个问题,呼吁大家抓紧检查,即时解决这类问题,确保Android应用软件的整体质量。
正确处理Ordered Broadcasts相关推荐
- 有序广播Ordered broadcasts的使用
给多个接受者发送广播 logcat中显示: MainActivity.java中注册button,添加过滤器. 发送信息用putExtra. 定义广播声明一个类Broadcast1.java,Broa ...
- 为什么说“仁者不忧”?
子曰:"知者不惑,仁者不忧,勇者不惧." 智(知:通"智")者不惑,好理解,智者从不停止学习,不断更新自己的认知,对世界有一个清醒的认识:勇者不惧,好理解,勇者 ...
- Android10.0 四大组件与进程启动间关系
原文地址:https://skytoby.github.io/2019/Android%E5%9B%9B%E5%A4%A7%E7%BB%84%E4%BB%B6%E4%B8%8E%E8%BF%9B%E7 ...
- Android日志[进阶篇]五-阅读错误报告
Android日志[进阶篇]一-使用 Logcat 写入和查看日志 Android日志[进阶篇]二-分析堆栈轨迹(调试和外部堆栈) Android日志[进阶篇]三-Logcat命令行工具 Androi ...
- android学习笔记1
adb 常用命令 adb device adb kill-server adb start-server adb install adb uninstall adb pull adb push ...
- Android - Broadcast
10s执行不完就ANR异常. 一.概念 Broadcast运行在主线程,使用了观察者模式,基于消息的发布/订阅事件模型,将发送者和接收者解耦使得方便集成更易扩展. 全局广播 APP ↔ 系统 像电量低 ...
- Android开发关键知识点讲解
有下载:http://download.csdn.net/detail/zl594389970/6281471 Android应用程序架构 src/ java原代码存放目录 gen/ 自动生成目录 ...
- Android Activity的启动流程分析:以Launcher启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互
文章目录 一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity: Step 1. Laun ...
- Instrumentation框架分析及其使用
本文旨在从Android系统源码出发,简单梳理Instrumentation框架的行为及逻辑结构,供有兴趣的同学一起学习 从am instrument谈起 am instrument命令的执行 我们知 ...
最新文章
- @service注解_Spring 中 @Component、@Service 等注解如何被解析的
- 查找、下载基因序列的方法
- UNIX系统编程(一)
- MySQL exists后面的子查询使用
- 禁用Zuul的过滤器
- 树的同构(c语言静态链表实现)
- 《走遍中国》珍藏版(六)
- 抽象工厂模式 -- 大话设计模式
- sql server 内存_SQL Server内存性能指标–第3部分– SQL Server Buffer Manager指标和内存计数器
- 解决IE9下JQuery的ajax失效的问题
- 分布式为什么使用python
- C语言入门了解篇—C语言编译流程
- 我的世界php motd,ColorMOTD 彩色字体插件 | 我的世界 | MC世界侠
- PHP7函数大全(4553个函数)
- OCR开源代码库介绍
- 计算机主机接口有哪些,主机接口有哪些
- CapstoneCS5263|DP转HDMI 4K60HZ方案|替代PS176芯片
- 张飞硬件90天学习笔记——第01天个人记录,完整请看我的个人简介/主页
- 登陆器生成登陆器不显示服务器列表,GeeM2单机登录器读取不到列表怎么办?
- 超文本传输协议 - 白话篇
热门文章
- 如何免费开通微信公众号留言功能(上)
- 2022-2027年中国农村网络零售行业市场深度分析及投资战略规划报告
- 声卡是组成多媒体电脑必不可少的
- 03 # 网页元素的属性
- 2005年乔布斯stanford演讲全文
- str[]与*str的区别
- 用户行为分析面面观(之一)-----用户行为研究体系 + 特征1:差异性
- 计算机编程语言排行榜—TIOBE世界编程语言排行榜(2020年11月份最新版)
- ubuntu卡在Started gnome...上的问题
- 文本溢出及其在angular中失效的bug