自定义应用程序 class:构造函数与 onCreate()

Custom Application class: Constructor vs. onCreate()

我的一个 Android 应用程序使用自定义应用程序 class 来执行一些全局初始化。这是在 onCreate() 方法中完成的:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        someCustomInit();
    }
}

这工作正常,但现在我在开发人员控制台中发现了一个崩溃日志,表明 MyApplication.onCreate() 在崩溃发生时没有 运行 / 尚未完成:代码崩溃因为执行的某些初始化 MyApplication.onCreate() 未完成。

这怎么可能? 我假设 MyApplication.onCreate() 会 运行 在所有其他代码之前?对不对?

是否将 someCustomInit(); 移至 MyApplication 的构造函数而不是? 在应用程序对象具有之前,其他代码不应 运行已创建,对吗?

或者使用构造函数而不是 onCreate() 是否有任何副作用?

I assumed that MyApplication.onCreate() would run before all other code? Isn't that correct?

ContentProvider 个实例是在 Application 上调用 onCreate() 之前创建的。理论上,您的堆栈跟踪应该向您显示在您的初始化之前正在调用您的哪些代码。

Is it save to move someCustomInit(); to the constructor of MyApplication instead?

这取决于 someCustomInit() 中发生的事情。您的 Application 尚未初始化。

另一种可能性是覆盖attachBaseContext(),例如ACRA is hooked in。在那里,如果您的初始化需要 Context.

,则会向您传递一个可以使用的 Context 对象

Application class 是您应用程序进程的单例,但它的 onCreate() 不是第一个可能执行的代码。 Class 字段初始值设定项、构造函数以及任何 static 代码块(通常用于加载本机库)将首先执行。特别是 static 代码块将 运行 当 运行 加载 class 时。

通常,这不是问题,最安全的方法是将您的特定代码放在 onCreate() 方法中。

How is this possible?

这是可能的,因为 Application class onCreate 会为您应用的 每个进程 调用。

例如 Service 可以在单独的进程中启动,因此您的应用程序可以启动两次。我在使用 Yandex.Appmetrica 库时遇到过这种行为。其实还不错,因为库中的崩溃不会影响应用程序的其他部分。

Or are there any side effects from using the constructor instead of onCreate()?

来自documentation

The Application class, or your subclass of the Application class, is instantiated before any other class when the process for your application/package is created.

因此构造函数将被调用两次。有什么区别吗?

您应该将本应 运行 仅一次的代码移动到 Application class 之外的其他地方。可能在某些 Singleton 中会被 Launcher Activity 或 smth 调用。实际上,如果你看到 sources of Application class 你会看到评论:

There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality in a more modular way.