4

The code is like below:

public class MyTestHelperHelper {
    static MyTestApi storeApi = null;
    public static synchronized void initial(Application application) {
        if (storeApi == null) {
        storeApi = new MyTestApiImplImpl();
        storeApi.initiImplal(application);
       }
    }
    public static MyTestApi getInstance() {
        return storeApi;
    }
}

MyTestHelperHelper's initial method is called in Application's onCreate, which is in UI thread. MyTestHelperHelper's getInstance method is called in the Activity's onCreate, which is also in UI thread.

In most case, it works normally. But sometimes, it return null with MyTestHelperHelper's getInstance, which leads to the NPE when I do further operations.

Though the case is rare, I can see it several times in the crash report. I just don't quite understand why:

  1. There is no write to the "storeApi", except in the initial method.

  2. Both initial and getInstance is in main thread, because initial is called in Application onCreate, and getInstance is called in Activity onCreate.

  3. If my app is in background and process is killed, I think the application will be re-created when bring to foreground, so the initial is called.

Seems the NPE occurs only when

1.process starts without application's oncreate. OR

2.When memory is low, many process data, including static variables, classloaders, classes, etc, are cleaned, except the application instance stays in the process. Is it possible?

1
  • initial is called on Application onCreate, and getInstance is called onActivity onCreate, both are synchronous. Commented Apr 10, 2018 at 6:19

1 Answer 1

2

It is not possible that a process is newly created and Application.onCreate() is not called.

Whenever a process is created, Application.onCreate() will be called.

However there are certain scenarios where lifetime of static variables could be impacted.

Lifecycle of static variable starts with class been loaded by the JVM and ends with class being unloaded.

A static variable will remain alive as long as one of following won't happen:

  1. The class is unloaded due to low memory conditions.

    Note: In this case Application object still persists since it will be the last object to be deallocated. This deallocation cannot be controlled by apps but determined by OS. This could happen if your app is in background and OS wants to relinquish the memory.

  2. The process is killed -> Both static object and Application object are deallocated.

You can use onSaveInstanceState() and onRestoreInstanceState() to save and restore state of your static variable respectively.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks for this info. I don't know this before. Is there any further info about "Application object still persists since it will be the last object to be deallocated"?
You can refer here which says: 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.
yes. But what I want to know more is about the application as the last object to be deallocated:)
You can refer this article for it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.