11

我有一个应用程序,它有一个派生自 Application 类的类,并且注意到它的 onCreate() 方法被多次调用。除此之外,每次调用 onCreate() 时都会重置其静态变量的值。

这种行为只发生在 M 上,它不会发生在 L 上。我试图找出它是 M 中的错误还是 M 中的预期更改,或者应用程序架构存在一些基本的固有问题,这些问题一直处于休眠状态,直到现在用 M 表现出来。

每当调用广播接收器的 onReceive() 时,都会调用 Application 派生类的 onCreate()。没有创建 Application 类的多个实例 - onCreate() 在同一个对象实例上被调用,并且始终存在相同的应用程序上下文。

以下是一些代码片段,展示了这一观察结果:

public class MyApplication extends Application
{
    public static int debugVal = 5;

    public MyApplication ()
    {
        theApp = this;
    }

    public void onCreate ()
    {
        Log.v(TAG, "++++++++++++ onCreate() debugVal: " + debugVal);
        debugVal = 10;
        ....



public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive (Context context, Intent intent)
    {
    Log.v(TAG, "onReceive. debugVal: " + MyApplication.debugVal);
    ...

在 Marshmallow 上运行时,logcat 输出为:

831-1412/? I/ActivityManager Start proc 2244:com.company.redacted/u0a86 for broadcast com.company.redacted/com.company.redacted2.MyBroadcastReceiver
2244-2244/? V/MyApplication: ++++++++++ onCreate() debugVal: 5
2244-2244/? V/MyBroadcastReceiver: onReceive. debugVal: 10
...
831-1327/? I/ActivityManager: Start proc 3271.com.company.redacted/u0a86 for broadcast com.company.redacted2/com.company.redacted1.MyBroadcastReceiver
3271-3271/? V/MyApplication: +++++++++++ onCreate() debugVal: 5
....

了解如何多次调用 onCreate(),以及第二次调用 onCreate() 时 debugVal 如何丢失其值 10。当在 Lollipop 上运行相同的 .apk 时,不存在对 onCreate() 的第二次调用。

L 上的日志如下所示:

768-783/? I/ActivityManager: Start proc 2480:com.company.redacted/u0a84 for broadcast com/company.redacted1/com.company.redacted2/MyBroadcastReceiver
2480-2480/? V/MyApplication: +++++++++++ onCreate() debugVal:5
2480-2480/? V/MyBroadcastReceiver: onReceive. debugVal: 10
....
2480-2480/com.company.redaced1 v/MyBroadcastReceiver: onReceive. debugVal: 10

我想知道发生了什么并消除它,但如果我不能,是否可以用一些单例类替换 Application 类,其静态变量保证安全可靠并且只初始化一次?

这是一个预安装的应用程序,它在启动时启动(这是接收器侦听的意图之一),此时没有任何活动。

4

3 回答 3

3

你说 onCreate() 在同一个过程中被调用了两次,但这可能是不正确的。Marshmallow 很有可能更积极地杀死你的进程,或者因为可用的内存更少,或者只是因为更积极地杀死空闲包(请参阅这个问题以提及 'empty #17' 和提到 CACHED_EMPTY 的文档)。

要进行验证,请通过使用持久通知调用startForeground使您的服务成为前台服务。如果您的问题消失,则意味着操作系统正在杀死您的进程。

一般来说,您不应该依赖于在后台运行 - 使初始化尽可能惰性和细粒度,并使广播接收器等后台操作尽可能便宜。

于 2015-10-25T21:45:59.113 回答
0

静态变量不利于保持状态。原因是静态变量在生命周期和应用程序启动/关闭期间无法生存。您通常只将静态变量用于常量状态。这意味着具有相同初始值或常量的变量。

如果值发生变化,则应将其存储在诸如 Prefs 之类的存储中。


至于为什么您会多次调用 OnCreate;你能详细说明你正在实施什么样的广播接收器吗?

传入的意图可能会导致配置更改,从而破坏并重新创建应用程序。

于 2015-10-30T05:29:40.390 回答
0

请注意,在您显示的日志消息中,整个过程重新启动,因此再次调用 onCreate,您能否描述两个事件之间发生的情况,或者有关您的应用程序正在做什么以及什么可以触发杀死第一个过程并开始一个新的过程?

于 2015-10-28T20:21:05.077 回答