在 application.onCreate() 中发送 BroadcastIntent 会导致永远启动

Sending BroadcastIntent in application.onCreate() results in booting forever

我正在为我的硕士论文定制 android,它基于 CM12.1。

自定义 rom 的用例是捕获任意应用程序的使用数据,例如启动、关闭和调用不同的系统资源。所有这些都应该在正常使用 phone 时发生。目前我想利用应用程序 class 以便它在其 onCreate() 方法中发送广播意图。

[...]
class Application extends ContextWrapper implements ComponentCallbacks2 {
[...]
public void onCreate() {
    // fire intent for capturing
    Bundle bundle = new Bundle();
    if (mLoadedApk != null) {
        bundle.putString("PACKAGE_NAME", mLoadedApk.getApplicationInfo().packageName);
        bundle.putLong("CREATION_DATE", System.currentTimeMillis());
    }
    Intent intent = new Intent(Intent.ACTION_START_APP) // custom action added to Intent.java
        .putExtras(bundle);
    getApplicationContext().sendBroadcastAsUser(intent, android.os.Process.myUserHandle());
}
[...]
}

这样我可以记录应用程序启动的确切时间,但遗憾的是我的方法导致设备不再启动。刷新自定义映像并启动后,我卡在了氰基启动动画(这是动画,它没有冻结)。工作图像离开动画并在大约 2 分钟后开始 android(也是在闪存后首次启动)但是我的带有自定义 Application.java 的 rom 仍然在 >15 分钟后显示启动动画。

我知道可以使用 ActivityManager 定期检查 运行 应用程序,但由于这是不准确的并且会阻止 cpu 进入省电模式,我想使用这种方法。

如果我取消对 sendBroadcast 的注释,一切正常。所以我想问题是 ActivityManagerNative 还不是 运行 但我不确定这一点。

因为我无法使用 adb 获取日志,所以我不知道在哪个 point/why 引导失败。

你能告诉我如何检查是否满足发送请求的所有先决条件吗? 或者我可以仅在设备启动过程完成时发送我的 Intent 并扫描我相应的 BroadcastReceiver 中所有打开的应用程序,但我不知道如何(或者即使可能)检查启动过程是否完成。

提前致谢。

好的,我可以解决问题。

幸运的是 android 也想知道系统何时启动。 class ActivityManagerService 有一个设置标志 mCallFinishBootingfinishBooting() 函数。因此,为此标志添加 getter 是解决方案的一部分。我还将此 getter 添加到 IActivityManager 界面。剩下的问题是实现接口但没有 finishBooting() 方法的 ActivityManagerProxy(可以在 ActivityManagerNative.java 中找到)。

一些测试显示 ActivityManagerProxy 在引导期间未使用,因此此处的 getter 始终 returns 为真。

因此,通过使用下面的代码,我可以在启动过程完成后为每个应用程序在应用程序启动时发送广播。我不确定是否真的需要检查 null

if (ActivityManagerNative.getDefault() != null && ActivityManagerNative.getDefault().isCallFinishBooting())
        getApplicationContext().sendBroadcastAsUser(intent, android.os.Process.myUserHandle());