2

One of my Android apps uses a custom Application class to perform some global initialization. This done in the onCreate() method:

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.

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

Is it save to move someCustomInit(); to the constructor of MyApplication instead? 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()?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Andrei Herford
  • 17,570
  • 19
  • 91
  • 225

3 Answers3

2

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

ContentProvider instances are created before onCreate() is called on the Application. 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(); to the constructor of MyApplication instead?

That would depend on what is happening in someCustomInit(). Your Application is not initialized yet.

Another possibility is to override attachBaseContext(), such as how ACRA is hooked in. There, you are passed a Context object that you can use, if your initialization requires a Context.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
2

The Application class is a singleton for your app process, but its onCreate() is not the first possible code to execute. Class field initializers, the constructor as well as any static code blocks (often used for loading native libs) will execute first. The static code blocks, in particular, will run when the class is loaded by the runtime.

Normally, this is not a problem and your safest route is to put your specific code in the onCreate() method.

Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33
2

How is this possible?

It is possible since Application class onCreate is called for every process of your app.

For example Service can be started in separate process so your Application can be started twice. I have met this behaviour when used Yandex.Appmetrica library. 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()?

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.

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. Probably in some Singleton which will be called from Launcher Activity or smth. Actually if you see sources of Application class you will see that comment:

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

Andrey Danilov
  • 6,194
  • 5
  • 32
  • 56