【问题标题】:What is the difference between this implicit broadcast and the other way of doing the same via explicit broadcast?这种隐式广播与通过显式广播进行相同操作的其他方式有什么区别?
【发布时间】:2019-07-13 14:25:58
【问题描述】:

在 Android 中使用 implicit 和 explicit 两种类型的广播 - 对于隐式我们将在 AndroidManifest.xml 中声明广播,并且当某些应用发送带有动作的广播时,所有声明广播的应用在他们的清单中,该操作将被调用并完成工作。

由于 Android 从 O 强加了 background execution limits,我不能只发送包含 action 的意图的广播。我必须明确指定包名和接收类名。

现在通过这样做,我能够克服隐式广播限制

String action = "com.android.intent.CUSTOM";
Intent intent = new Intent();
intent.setAction(intent);

//Though this is a deprecated method
List<ResolveInfo> resolvedBroadcasts = List<ResolveInfo> queryBroadcastReceivers(intent, 0, current_user_id);

for (ResolveInfo info : resolvedBroadcasts) {
   ServiceInfo serviceInfo = info.serviceInfo;

   //Note: Now this is becoming explicit broadcast
   intent.setAction(serviceInfo.packageName, serviceInfo.name);
   context.sendBroadcast(intent);
}

我在这里遗漏了什么吗?在这一点上感到困惑,如果我能够这样做,那么为什么 Android 会给我施加这个后台执行限制?

【问题讨论】:

    标签: android android-8.0-oreo android-broadcast


    【解决方案1】:

    我错过了什么吗?

    Google 工程师表示,如果有太多应用这样做,这种方法会以某种方式被禁止。

    FWIW,我在博客上写过这种方法 two years ago。

    如果我能够做到这一点,那么为什么 Android 会对我施加这种后台执行限制?

    Google 希望很少有开发人员会采用这种解决方法,而是会使用其他一些 IPC 机制。

    问题是流程流失。假设您的隐式广播匹配 25 个应用程序的清单。当您的代码执行时,Android 需要将您的 Intent 传递给 25 个接收者。但是,其中只有几个会在内存中——许多应用程序不会有正在运行的进程。因此,Android 现在需要派生一大堆进程来传递您的Intent。这反过来可能会强制终止其他进程,以释放系统 RAM。最终结果是在低端设备上性能不佳。

    我认为,与其禁止隐式广播,Android 应该实现存储转发机制,以限制进程流失的速度缓慢地传递广播。我的建议被拒绝了。

    【讨论】:

    • +1 表示store-and-forward 方法。虽然与此主题无关​​,但是否有人遇到过广播在交付之前超时的问题?我面临这个问题可能是我认为广播队列已满,并且在配置超时之前传递消息需要时间。
    • 我需要一个建议。当我正在执行某些操作时,我需要通知其他应用程序该操作已经发生 - 在这种情况下,哪种是将事件传达给其他进程的更快方法?更清楚地说,在我的情况下,其他应用程序可能是 3 或 4。但我不会知道所有我在编译时不会知道的应用程序。所以,寻找一些动态的方式来实现同样的目标。
    • 我仍然无法相信你在 2 年前就已经想通了。 :o 太好了!
    • @gooogle:“有人遇到过广播在送达前超时的问题吗?” ——我不确定你的意思是什么,抱歉。 “我需要通知其他应用程序该操作已经发生”——这些应用程序是否需要知道,即使它们的进程没有运行?他们能简单地找出他们下次跑步的时间吗?
    • 当我在低端设备(内存和 cpu 较差)上运行我的代码时,我有时会观察到我的广播被错过了(未交付) - 那么我怎么说我没有接收广播?我在onReceive 方法的开头(也在sendBroadcast 之前)有一个我没有看到的日志打印。我认为为什么这个广播没有传递的一个原因是,广播队列可能已经填满,所以它可能需要一些时间(~15 秒),所以当它尝试传递时它可能已经超时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    相关资源
    最近更新 更多