我的一个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()
会产生任何副作用吗?
答案 0 :(得分:2)
这怎么可能?
由于您的应用的每个进程都会调用Application
类onCreate
,因此可以这样做。
例如Service
可以在单独的进程中启动,因此您的应用程序可以启动两次。使用Yandex.Appmetrica
库时,我遇到了这种情况。实际上并不错,因为库中的崩溃不会影响应用程序的其他部分。
或使用构造函数而不是有任何副作用 的onCreate()?
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()
方法中。