简体   繁体   English

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

[英]Custom Application class: Constructor vs. onCreate()

One of my Android apps uses a custom Application class to perform some global initialization. 我的一个Android应用程序使用自定义Application类执行一些全局初始化。 This done in the onCreate() method: 这是在onCreate()方法中完成的:

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

This works fine, but now I have discovers a crash log in the Developer Console which indicated that MyApplication.onCreate() did not run / has not completed at the time the crash happened: The code crashed because some initialization that is performed MyApplication.onCreate() was not complete. 这项工作正常,但是现在我在开发人员控制台中发现了一个崩溃日志,该日志指示MyApplication.onCreate()在崩溃发生时没有运行/尚未完成:代码崩溃了,因为执行了一些MyApplication.onCreate()初始化MyApplication.onCreate()不完整。

How is this possible? 这怎么可能? I assumed that MyApplication.onCreate() would run before all other code? 我假设MyApplication.onCreate()将在所有其他代码之前运行? Isn't that correct? 那不正确吗?

Is it save to move someCustomInit(); 移动someCustomInit();是否省钱someCustomInit(); to the constructor of MyApplication instead? 改为MyApplication的构造函数? No other code should run before the application object has been created, correct? 在创建应用程序对象之前,不应运行任何其他代码,对吗?

Or are there any side effects from using the constructor instead of onCreate() ? 还是使用构造函数代替onCreate()有任何副作用?

How is this possible? 这怎么可能?

It is possible since Application class onCreate is called for every process of your app. 这是有可能的,因为您的应用程序的每个进程都会调用ApplicationonCreate

For example Service can be started in separate process so your Application can be started twice. 例如, Service可以在单独的过程中启动,因此您的应用程序可以启动两次。 I have met this behaviour when used Yandex.Appmetrica library. 使用Yandex.Appmetrica库时,我遇到了这种Yandex.Appmetrica It is not bad actually, because crashes in library will not affect other parts of application. 实际上,这还不错,因为库崩溃不会影响应用程序的其他部分。

Or are there any side effects from using the constructor instead of onCreate()? 还是使用构造函数代替onCreate()有任何副作用?

From the 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类或Application类的子类。

So constructor will be called twice. 因此,构造函数将被调用两次。 Any difference? 有什么区别吗?

You should move your code that supposed to run only once to somewhere else, outside Application class. 您应该将应该只运行一次的代码移到Application类之外的其他地方。 Probably in some Singleton which will be called from Launcher Activity or smth. 可能在某些Singleton ,这将从Launcher Activity或smth中调用。 Actually if you see sources of Application class you will see that comment: 实际上,如果您看到Application类的源代码 ,则会看到以下注释:

There is normally no need to subclass Application. 通常不需要子类化Application。 In most situations, static singletons can provide the same functionality in a more modular way. 在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。

I assumed that MyApplication.onCreate() would run before all other code? 我假设MyApplication.onCreate()将在所有其他代码之前运行? Isn't that correct? 那不正确吗?

ContentProvider instances are created before onCreate() is called on the Application . ContentProvider实例是在Application上调用onCreate()之前创建的。 In theory, your stack trace should show you what code of yours is being invoked prior to your initialization. 从理论上讲,堆栈跟踪应该显示初始化之前正在调用的代码。

Is it save to move someCustomInit(); 移动someCustomInit()是否省钱? to the constructor of MyApplication instead? 改为MyApplication的构造函数?

That would depend on what is happening in someCustomInit() . 那将取决于someCustomInit()发生的事情。 Your Application is not initialized yet. 您的Application尚未初始化。

Another possibility is to override attachBaseContext() , such as how ACRA is hooked in . 另一种可能性是重写attachBaseContext() ,例如ACRA的挂钩方式 There, you are passed a Context object that you can use, if your initialization requires a Context . 如果初始化需要Context ,则会向您传递一个可以使用的Context对象。

The Application class is a singleton for your app process, but its onCreate() is not the first possible code to execute. Application类是您的应用进程的单例,但是其onCreate()并不是第一个可能执行的代码。 Class field initializers, the constructor as well as any static code blocks (often used for loading native libs) will execute first. 类字段初始化程序,构造函数以及任何static代码块(通常用于加载本机lib)将首先执行。 The static code blocks, in particular, will run when the class is loaded by the runtime. 特别是, static代码块将在运行时加载类时运行。

Normally, this is not a problem and your safest route is to put your specific code in the onCreate() method. 通常,这不是问题,最安全的方法是将特定的代码放在onCreate()方法中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM