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

时间:2018-06-05 11:16:17

标签: java android constructor oncreate

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

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

这很好用,但现在我在Developer Console中发现了一个崩溃日志,表明MyApplication.onCreate()在崩溃发生时没有运行/没有完成:代码崩溃,因为执行了一些初始化MyApplication.onCreate()未完成。

这怎么可能?我认为MyApplication.onCreate()会在所有其他代码之前运行?这不正确吗?

someCustomInit();移动到MyApplication的构造函数是否保存?在创建应用程序对象之前是否应该运行其他代码,对吗?

或者使用构造函数而不是onCreate()会产生任何副作用吗?

3 个答案:

答案 0 :(得分:2)

  

这怎么可能?

由于您的应用的每个进程都会调用ApplicationonCreate,因此可以这样做。

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

  

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

来自documentation

  

Application类或Application类的子类是   在你的任何其他类之前实例化的过程   应用程序/包已创建。

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

您应该将应该只运行一次的代码移到Application类之外的其他地方。可能在某些Singleton中将从Launcher Activity或smth调用。实际上,如果您看到Application课程sources,您会看到该评论:

  

通常不需要子类Application。在大多数情况下,   静态单例可以在更模块化的情况下提供相同的功能   方式。

答案 1 :(得分:1)

  

我认为MyApplication.onCreate()会在所有其他代码之前运行吗?这不正确吗?

ContentProvider上调用onCreate()之前创建

Application个实例。理论上,堆栈跟踪应该显示在初始化之前调用了哪些代码。

  

移动someCustomInit()是否保存;改为MyApplication的构造函数?

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

另一种可能性是覆盖attachBaseContext(),例如ACRA is hooked in。在那里,如果您的初始化需要Context,则会传递一个Context对象供您使用。

答案 2 :(得分:1)

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

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