忙啊~最近好忙呀。html
忙的我连SystemUI系列的文章推动向蜗牛同样慢~java
这篇文章偷个闲,记录下Android8.0上的广播限制。android
最近在基于Android 8.1的系统项目中有用到静态注册广播去监听广播。但是不论我是普通的将Apk install进去抑或是高贵的push到对应的system/priv-app/目录下,都收不到这个广播。心态,DUANG,炸了。安全
后来灵光一闪,扒出记忆角落的Android7.0的广播限制,赶忙Google一下。原来如此,恍然大悟:**Android8.0后,当App targetSDK >= 26,几乎禁止了全部的隐式广播的静态注册监听。**特在此记录,防止我之后又提莫的忘记了。 微信
本篇文章主要讲述如下内容,还请拿起小板凳,带好零食,前来观赏:网络
来来来,先科普下,广播两种监听/接收注册方式和两种类型,拿小本本记下来,记住了!app
注册方式:ide
两种类型:ui
Intent.setComponent()
Intent.setClassName()
Intent.setClass()
new Intent(A.this,B.class)
复制代码
注意是针对targetSDK >= 26的应用,也就是说,targetSDK小于26的话,暂不受影响this
在Oreo中,为了进一步提高用户体验,进一步节省功耗,对应用在后台运行时能够执行的操做又进一步施加了限制。
后台服务限制:处于空闲状态时,限制应用的后台服务。例如:经过静态注册接收开机广播(假设你的设备没作定制,能收到~),并在onReceive方法中启动一个Service,在API 26上,是不容许且会报错的。固然,对于前台服务,这种限制是不存在的。官方说法是:前台服务更容易引发用户注意。
广播限制:除了有限的例外以外,应用没法使用清单注册(静态注册)的方式来接收隐式广播。
这里多说一句,Android手机的卡顿,很大程度是因为应用滥用且自私的使用各类手段(权限滥用,广播注册,后台服务常驻等)保活或作一些PY事情。Google显然很早就意识到这一点,并从Android 6.0 开始就逐步引入各类限制,好比运行时权限和Doze。
若是应用注册了广播接收器,那么每次发送广播后,应用的广播接收器就会消耗资源,如RAM,CPU等。若是有不少应用对系统事件广播注册广播接收器,这....,就会很卡的嘛!
因此从Android 7.0 (API 级别 24)开始,就对广播作了一些限制:
只不过,在Android8.0上,又进一步的加强了限制,除了如下隐式广播外,其余全部隐式广播均没法经过在AndroidManifest.xml中注册监听。参考官网。
// Android 8.0 上不限制的隐式广播
/** 开机广播 Intent.ACTION_LOCKED_BOOT_COMPLETED Intent.ACTION_BOOT_COMPLETED */
"保留缘由:这些广播只在首次启动时发送一次,而且许多应用都须要接收此广播以便进行做业、闹铃等事项的安排。"
/** 增删用户 Intent.ACTION_USER_INITIALIZE "android.intent.action.USER_ADDED" "android.intent.action.USER_REMOVED" */
"保留缘由:这些广播只有拥有特定系统权限的app才能监听,所以大多数正常应用都没法接收它们。"
/** 时区、ALARM变化 "android.intent.action.TIME_SET" Intent.ACTION_TIMEZONE_CHANGED AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED */
"保留缘由:时钟应用可能须要接收这些广播,以便在时间或时区变化时更新闹铃"
/** 语言区域变化 Intent.ACTION_LOCALE_CHANGED */
"保留缘由:只在语言区域发生变化时发送,并不频繁。 应用可能须要在语言区域发生变化时更新其数据。"
/** Usb相关 UsbManager.ACTION_USB_ACCESSORY_ATTACHED UsbManager.ACTION_USB_ACCESSORY_DETACHED UsbManager.ACTION_USB_DEVICE_ATTACHED UsbManager.ACTION_USB_DEVICE_DETACHED */
"保留缘由:若是应用须要了解这些 USB 相关事件的信息,目前还没有找到可以替代注册广播的可行方案"
/** 蓝牙状态相关 BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED BluetoothDevice.ACTION_ACL_CONNECTED BluetoothDevice.ACTION_ACL_DISCONNECTED */
"保留缘由:应用接收这些蓝牙事件的广播时不太可能会影响用户体验"
/** Telephony相关 CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED TelephonyIntents.ACTION_*_SUBSCRIPTION_CHANGED TelephonyIntents.SECRET_CODE_ACTION TelephonyManager.ACTION_PHONE_STATE_CHANGED TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED */
"保留缘由:设备制造商 (OEM) 电话应用可能须要接收这些广播"
/** 帐号相关 AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION */
"保留缘由:一些应用须要了解登陆账号的变化,以便为新账号和变化的账号设置计划操做"
/** 应用数据清除 Intent.ACTION_PACKAGE_DATA_CLEARED */
"保留缘由:只在用户显式地从 Settings 清除其数据时发送,所以广播接收器不太可能严重影响用户体验"
/** 软件包被移除 Intent.ACTION_PACKAGE_FULLY_REMOVED */
"保留缘由:一些应用可能须要在另外一软件包被移除时更新其存储的数据;对于这些应用,还没有找到可以替代注册此广播的可行方案"
/** 外拨电话 Intent.ACTION_NEW_OUTGOING_CALL */
"保留缘由:执行操做来响应用户打电话行为的应用须要接收此广播"
/** 当设备全部者被设置、改变或清除时发出 DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED */
"保留缘由:此广播发送得不是很频繁;一些应用须要接收它,以便知晓设备的安全状态发生了变化"
/** 日历相关 CalendarContract.ACTION_EVENT_REMINDER */
"保留缘由:由日历provider发送,用于向日历应用发布事件提醒。由于日历provider不清楚日历应用是什么,因此此广播必须是隐式广播。"
/** 安装或移除存储相关广播 Intent.ACTION_MEDIA_MOUNTED Intent.ACTION_MEDIA_CHECKING Intent.ACTION_MEDIA_EJECT Intent.ACTION_MEDIA_UNMOUNTED Intent.ACTION_MEDIA_UNMOUNTABLE Intent.ACTION_MEDIA_REMOVED Intent.ACTION_MEDIA_BAD_REMOVAL */
"保留缘由:这些广播是做为用户与设备进行物理交互的结果:安装或移除存储卷或当启动初始化时(当可用卷被装载)的一部分发送的,所以它们不是很常见,而且一般是在用户的掌控下"
/** 短信、WAP PUSH相关 Telephony.Sms.Intents.SMS_RECEIVED_ACTION Telephony.Sms.Intents.WAP_PUSH_RECEIVED_ACTION 注意:须要申请如下权限才能够接收 "android.permission.RECEIVE_SMS" "android.permission.RECEIVE_WAP_PUSH" */
"保留缘由:SMS短信应用须要接收这些广播"
复制代码
呼,终于列完了,以上。能够说写的比官网还全~
建议收藏一波防止之后用的到哈。
按照官方推荐,对于隐式广播,经过如下方法进行替换。
Context.registerReceiver()
注册广播接收器而不是在清单中声明接收器。我选择动态注册的方式来处理这个问题。
好了,关于Oreo的广播限制的唠嗑就先唠到这里。
最近受到一位小伙伴的启发,获得一句话:努力的人,运气和机遇每每都不会差!
共勉!
最后,欢迎关注微信公众号:猿湿Xoong
开心的进行Android高质量干货分享
[1] Android Oreo 后台执行限制 https://developer.android.com/about/versions/oreo/background#broadcasts
[2] Android Oreo Implicit Broadcast Exceptions https://developer.android.com/guide/components/broadcast-exceptions
[3] Android中显式和隐式intent的特色和区别 https://blog.csdn.net/u014177843/article/details/50596863
[4] Android O行为变动--隐式广播限制 https://blog.csdn.net/hqocshheqing/article/details/76850164