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…