preface

In the previous article, I reviewed the correct use of Android Applications from getApplicationContext and getApplication

But we know that mApplication and Context are two different things, so strictly getApplicationContext and getApplication are not the same, even though many times they return the same object

Notice that the two methods return different objects, because I saw that the two methods return two objects in the Activity, I simply assumed that they were really different.

Looking for different

As a correction and supplement today, let’s move on to the code to see if they are really different, or if there are similarities:

public abstract Context getApplicationContext();
Copy the code

GetApplicationContext is an abstract method, which is implemented in ContextImpl:

@Override
    public Context getApplicationContext() {
        return(mPackageInfo ! = null) ? mPackageInfo.getApplication() : mMainThread.getApplication(); }Copy the code

Let’s look at the getApplication method (only available in activities and Services) :

public final Application getApplication() {
        return mApplication;
    }
Copy the code

So where’s the mApplication assignment? If you search, there is only one place that has an assignment:

final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config, String referrer, IVoiceInteractor voiceInteractor) { attachBaseContext(context); . mApplication = application; }Copy the code

In the last article, I saw that the two methods returned different objects, but we ignored getApplicationContext, When mPackageInfo is not null and empty is called mPackageInfo respectively. The getApplication () and mMainThread getApplication (), That getApplicationContext exactly return with mApplication have what different, take a look at these two methods, in LoadedApk. See mPackageInfo. Java getApplication () :

Application getApplication() {
        return mApplication;
    }
Copy the code

There is also an mApplication in LoadedApk, and this mApplication is assigned to the makeApplication in LoadedApk:

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
...
if(mApplication ! = null) {returnmApplication; } Application app = null; . app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); . mActivityThread.mAllApplications.add(app); mApplication = app; . }Copy the code

See first of all, is an empty judgment (singleton), empty words has built an Application and then assigned to mApplication, we’ll look at mMainThread. GetApplication () returns, in ActivityThread. In Java:

public Application getApplication() {
        return mInitialApplication;
    }
Copy the code

Let’s see where the mInitialApplication assignment is:

private void handleBindApplication(AppBindData data) { ... Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; . }Copy the code

So we’ve got makeApplication, and data.info is also LoadedApk, and we can see it here, and we’re going to end up with the same thing all the way around, but maybe at different times, one in LoadedApk, one in ActivityThread, But in the end we find that getApplicationContext() returns all mApplication.

The truth

In LoadedApk we see a thing called mApplication, and in Activity we see a thing called mApplication. Are they related to each other? Take a look at the assignment of mApplication in the Activity, which is found in the attach method (I left out the other parameters in the method) :

final void attach(Application application) {
mApplication = application;
}
Copy the code

So that’s equal to the attach method of the application, where is the attach method of the Activity called, so we’re going to go to the oft-mentioned application entry class ActivityThread, which has a formLaunchActivity method, To load an Activity, here’s the attach() call (I left out the other parameters) :

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Application app = r.packageInfo.makeApplication(false, mInstrumentation); . activity.attach(app); . }Copy the code

We found it again… MakeApplication (), r.packageInfo (LoadedApk), makeApplication(), r.packageInfo (LoadedApk)

The results of

The result is obvious. The title problem is solved. Do getApplicationContext and getApplication return the same object? A: Yes!

Of course, they are the same premise is that mApplication is not empty, then again, this is the global context, the program is started how it can be empty, as for it exactly what circumstances will cause the return of the object is not the same, wait for the advanced continue to break down…