Android8.0的广播-熟悉的陌生人

Android 8.0正式版上线到现在已经有一年了,很多厂商的2018年的机型上已经用上了这个系统。

8.0 的系统代号是 Orea,对..奥利奥, 新系统有很多行为上的变更,今天说一下比较有意思的广播行为上的新政策。

8.0前的广播

做Android的都知道广播是四大组件之一, 它有两种注册方式,

  • AndroidManifest注册的静态广播
  • registerReceiver注册的动态广播

在8.0以前这了两种方式注册的广播都是有效的,除了接收时机的差异之外,没有什么限制。

做过项目的同学应该对 ACTION_BOOT_COMPLETED 这个系统广播很熟悉, 很多时候我们会用这个广播在系统启动后用来拉起自己的应用, 在几年前的是这个保活手段还算有用, 但是在后来各大厂商的系统管理机制完善起来后也就渐渐失效了。

笔者曾经闲的无聊去分析了在手机上监听这个广播的app, 发现竟然有70+个进程在监听它。。 这种现象会导致在系统启动后变的很慢很卡,毕竟要开70+个进程,RAM也受不了, 所以几年前的Android机的慢和卡的通病..大部分原因是流氓软件导致的..

Google认识到这个问题后慢慢的在系统机制上进行迭代,下面是一段来自Google FW团队Dianne Hackborn的原文,

To help understand what is going on, I need to clarify that the purpose of this change is not directly related to battery use, but rather to address long-standing issues we have had in the platform where devices that are under memory pressure can get in to bad thrashing states. Very often these states are due to broadcasts: some broadcast or broadcasts are being sent relatively frequently, which a lot of applications are listening to through their manifest (so need to be launched to receive it), but there is not enough RAM to keep all of those app proceses in cache, so the system ends up continually thrashing through processes each time the broadcast is sent.

翻译过来的意思是说,8.0对广播机制的修改对电池的优化是次要的, 主要的原因是来自内存的压力,因为太多静态注册的广播了,系统不得不开很多进程来维护这些广播,导致消耗了大量的内存。 所以解决方案是什么呢, 不再使用隐式静态广播

8.0之后的广播

如果你在8.0+开发中遇到这样的问题

04-11 14:12:36.340 753-763/? W/BroadcastQueue: Background execution not allowed: receiving Intent

那么八成是发了个隐式静态广播的原因了。 要导致这个问题只需要两个条件,

  • 在manifest中静态注册了广播
  • 发送广播时没有指定包名

当然这里有个前提条件是 targetSdk > 25,低版本的app即使在8.0系统上也不会受到这个政策的影响。 就算发的隐式广播是在自己的app里的AnroidManifest上注册的,在8.0上也照样收不到。

解决办法目前有三种,

  • 修改 targetSdk < 26
  • 动态注册广播,用 registerReceiver注册的不受影响
  • 发广播的时候指定包名

对于第三个方法,如果要发广播给其他进程怎么办呢,这里给一段简单代码, 思路就是获取注册了这个广播action的接收器,然后拿他们的包名,构造一个显示广播再发出去,

private static void sendImplicitBroadcast(Context ctxt, Intent i) {
  PackageManager pm=ctxt.getPackageManager();
  List<ResolveInfo> matches=pm.queryBroadcastReceivers(i, 0);

  for (ResolveInfo resolveInfo : matches) {
    Intent explicit=new Intent(i);
    ComponentName cn=
      new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName,
        resolveInfo.activityInfo.name);

    explicit.setComponent(cn);
    ctxt.sendBroadcast(explicit);
  }
}

==== 今日沙雕 ====

原文发布于微信公众号 - Android每日一讲(gh_f053f29083b9)

原文发表时间:2018-08-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏吴裕超

要不要用gzip优化前端项目

这两天在做项目优化,注意到webpack有一个compression-webpack-plugin插件,可以打包成gzip格式部署到服务器,了解到了GZIP,其...

1K8
来自专栏FreeBuf

更适合作为主系统使用的Parrot Security简介

Parrot 是一个基于Debian的专注于渗透测试和隐私保护的Linux发行版,但是更加方便日常使用,有贴心的使用体验,丰富的工具,更注重隐私保护。 The...

8355
来自专栏小白课代表

最优秀好用的免费文件压缩/解压缩工具软件

若常常需要与 Mac 用户交换文件,或是购买一些国外的数字商品(如我购买的日本同人志),常常会遇见压缩包打开是一片一片的乱码文件名的状况。编码问题一直是造成乱码...

1061
来自专栏影子

springMVC项目国际化(i18n)实现方法

3539
来自专栏熊二哥

Linux快速入门01-基础概念

4年多前,刚到上海时报过一个关于Oracle的培训班,在那里接触到了Linux,不过一直都没真正去试着使用它。现在经过慢慢的成长,越来越觉得,Linux是每一个...

2285
来自专栏Android群英传

Siri 帮我开灯

1092
来自专栏FreeBuf

搭建dvwa环境学习从MySql注入到GetShell

是啊,在项目上的系统每周每个月经过几十遍的过滤,平时看到提交参数的地方也就sqlmap跑一跑,对于最基础的手工注入都没有扎实的学会,于是我决定要知道如何搭建环境...

1703
来自专栏Fundebug

XSS攻击之窃取Cookie

译者按: 10 年前的博客似乎有点老了,但是XSS 攻击的威胁依然还在,我们不得不防。

1755
来自专栏农夫安全

运维的福利,黑客的噩梦

CYWL_Team服务器防御工具1.0 0x01开发前言 很多小黑都希望搭建自己的博客,论坛,来记录自己在安全之路上面的点点滴滴,不过总是被一些大牛来进行恶搞,...

3858
来自专栏linux系统运维

负载均衡集群介绍,LVS介绍, LVS调度算法,LVS NAT模式搭建

1912

扫码关注云+社区

领取腾讯云代金券