Android 是什么让广播接收者这么晚才得到它的意图? 背景

Android 是什么让广播接收者这么晚才得到它的意图? 背景,android,broadcastreceiver,android-phone-call,Android,Broadcastreceiver,Android Phone Call,我们有一个大型应用程序,它具有各种功能,使用多个库,并使用广播接收器处理电话: <receiver android:name="....PhoneBroadcastReceiver"> <intent-filter > <action android:name="android.intent.action.PHONE_STATE"/> </intent-filter>

我们有一个大型应用程序,它具有各种功能,使用多个库,并使用
广播接收器处理电话:

    <receiver android:name="....PhoneBroadcastReceiver">
        <intent-filter >
            <action android:name="android.intent.action.PHONE_STATE"/>
        </intent-filter>
        <intent-filter >
            <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
        </intent-filter>
    </receiver>

),用于电话录音,如果我在
BroadcastReceiver
中添加日志,而不是真正的逻辑,我可以看到它立即得到处理。我甚至将这个大型应用程序的所有权限都添加到了我制作的这个示例应用程序中(并授予了它们),它仍然工作得非常好。遗憾的是,添加大型应用程序使用的库可能需要大量时间来添加和测试

  • 我在想,可能是从应用程序(或者确切地说是
    MultiDexApplication
    )扩展的类占用了太多时间,所以我在那里添加了一个日志(从
    onCreate
    开始)。它确实需要一点时间(一秒钟左右),但日志会在一段时间后显示,并且它与
    广播接收器的日志之间的差异非常小。因此,问题应该是由比应用程序或
    BroadcastReceiver
    更深的原因引起的

  • 我想可能是因为我们使用多重索引。我试图禁用它,但没用。我甚至不认为这会影响它,因为我已经在像素2上的Android P上尝试过了

  • 我试图设置
    广播接收器的优先级。试图将其设置为999(这是最重要的),甚至设置为2147483647,但都没有起到任何作用

  • 我想可能操作系统正在为应用程序分配大量内存,这可能需要一些时间,但我知道,即使在我从最近的任务中关闭应用程序后,其他侦听相同意图的应用程序(如TrueCaller)也可以正常工作。我还测试了应用程序使用了多少内存,以及TrueCaller使用了多少内存。该应用程序在my Pixel 2上平均使用33MB的总RAM,而TrueCaller使用2MB。我从开发者选项屏幕上得到了这些值,即“内存使用率”。奇怪的是,它告诉我,即使从头启动应用程序,最大内存使用量也是巨大的(大约1GB),但我从来没有在分析器中看到过,甚至没有接近(大约200MB)。我认为这个屏幕不是检查内存使用情况的可靠方法

  • 我认为也许将应用程序排除在电池优化之外会有所帮助,但事实并非如此。在这种情况下,即使是向用户请求此功能的TrueCaller也并不真正需要它。它在那里运行良好,无需设置

  • 我认为唯一的原因可能是应用程序使用的库。还有很多,但我想知道在扩展应用程序的类被调用之前,什么会影响应用程序。。。可悲的是,有这么多,将它们全部添加到POC项目中需要很多时间。我想我会这么做,但我不知道这是否真的是原因

  • 问题
  • 什么可能会影响广播接收器这么晚才达到目的?这可能是我提到的事情之一吗

  • 为什么“内存使用”屏幕看起来如此不可靠,并且与我在IDE分析器上看到的内容相矛盾?这可能是延迟意图(操作系统的巨大内存分配)的原因吗


  • 编辑:我注意到一些库的初始化在扩展应用程序的类的onCreate调用中花费了太多的时间,所以我将其中一些放在后台线程中,有些甚至已经删除


    这似乎更好,但问题是,手机铃声响起后,应用程序触发得太晚,因此问题仍然存在。

    好的,似乎我错了,这一意图可能会晚一点收到,这取决于操作系统,也可能取决于应用程序的亮度

    我现在这样想的原因是,我注意到,即使是TrueCaller也不总是立即出现。有时候,他们也会花很长时间

    因此,我认为倾听这些意图是安全的唯一方式,是通过编程而不是通过清单

    在前台服务中有类似的含义:

            telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            telephonyManager!!.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
    

    我能说的是,如果该应用程序被授予了通知访问权限,那么它总是处于活动状态的可能性非常大,因此它不需要前台服务。

    不保证在特定的时间范围内达到目的。如果你的应用程序真的需要它,它就会永久性地坏掉。我知道,没有办法保证。@GabeSechan,但似乎其他应用程序在手机铃声响起时处理得很好。即使是在POC中我也看到了。然后是时候真正投入进去,弄清楚什么需要时间了。由于应用程序已关闭,profiler不会有多大帮助。因此,我建议使用良好的旧printf调试来确定应用程序的每个步骤需要多少时间。onCreate需要多少时间,看看是什么花费了这么多时间。@Gabeschen我已经做过了。见#2。我已将日志放在扩展应用程序类的类的
    onCreate
    的第一行(确切地说是
    MultiDexApplication
    )。问题是,即使在那里,我也看到,与电话开始响相比,它被叫得很晚。当然,我会继续调查。@Gabeschen我已经进一步测试过了。似乎onCreate相当慢,但即使在修复它后花费的时间要少得多,问题还是在它被调用之前,因为它的调用方式是在电话铃响之后。