In app development, we need to use app resources, such as text, pictures, Activity, Service or broadcastReceiver. getApplicationContext() is often used to get a Context object. So what exactly is this Context?
Introduction to Context class
Context means context, context, background, environment, etc. Context is a core function class to maintain the normal operation of components in Android programs.
Context is an abstract class. It is an "interface" of the app global environment. The Android system provides inheritance classes (such as activity, Service, Application, etc.). It can connect to Application resources and use Application level operations, such as starting activity, broadcasting and receiving intent.
The total number of contexts in the application is: total number of contexts = number of activities + number of services + 1 (Application Context)
Subclass of Context
Simple inheritance diagram
Context ├── ContextImpl └── ContextWrapper ├── Application ├── ContextThemeWrapper │ └── Activity └── Service
As can be seen from the inheritance diagram, Application class, Service class and Activity class all inherit the Context class. After the Application is started, a global Context object corresponding to the Application will be created for the Application. The ContextImpl class is the real implementation of Context.
The ContextWrapper class is an encapsulation class. You can add some custom operations for ContextImpl without changing it. The mBase in the ContextWrapper is actually a ContextImpl object. The mOuterContext in the ContextImpl class is a Context object that points to the corresponding Activity or Service or Application.
ContextImpl
Context is an abstract class, and the subclass contextimpl implements the method of context; Provide basic context objects for activities and other application components. ContextImpl.java (frameworks\base\core\java\android\app)
/** * Common implementation of Context API, which provides the base * context object for Activity and other application components. */ class ContextImpl extends Context { /*...*/ }
ContextWrapper
Wrapper means encapsulation; ContextWrapper is an encapsulated class of Context. The decorator pattern is used here, and a Context instance is passed in the construction method. The ContextWrapper holds the ContextImpl object. You can add some operations without changing the ContextImpl.
ContextWrapper.java (frameworks\base\core\java\android\content)
/** * Proxying implementation of Context that simply delegates all of its calls to * another Context. Can be subclassed to modify behavior without changing * the original Context. */ public class ContextWrapper extends Context { Context mBase; public ContextWrapper(Context base) { mBase = base; } // ... }
In the specific operation, the Application class, Activity and Service class intersect with ContextImpl.
ContextThemeWrapper
It is allowed to modify the theme in the encapsulated context
ContextThemeWrapper.java (frameworks\base\core\java\android\view)
/** * A ContextWrapper that allows you to modify the theme from what is in the * wrapped context. */ public class ContextThemeWrapper extends ContextWrapper { /* ... */ }
It provides methods about theme, which is related to android:theme in app development. The same code, the same call, and using different themes will have different effects.
getApplicationContext() and getBaseContext()
public class ContextWrapper extends Context { Context mBase; ...... @Override public Context getApplicationContext() { return mBase.getApplicationContext(); } ...... /** * @return the base context as set by the constructor or setBaseContext */ public Context getBaseContext() { return mBase;// Don't use getBaseContext(), just use the Context you have. } ...... }
getApplicationContext() = android.app.Application@39d42b0e getBaseContext() = android.app.ContextImpl@1f48c92f
getApplicationContext() gets the context from the application. getBaseContext() is derived from the implementation class ContextImpl.
Context subclass creation process
Application creation process
We focus on the application first and ignore other information in the source code for the time being.
Process Description:
LoadedApk first obtains the Application class through loadClass(className) of classLoader, and then through clazz Newinstance() creates an Application instance. Then call app The attach (context) method completes initialization.
The attach method of Application calls its own attachBaseContext(context), and assigns the ContextImpl instance created in the first step to the mBase member variable of ContextWrapper. The creation of this Application instance is complete.
Activity creation - performlunchactivity
The focus here is on the instantiation of Activity and some previous preparation processes.
Process analysis:
It mainly focuses on the performLaunchActivity method of ActivityThread. Obtain a ContextImpl instance called appContext through the createActivityContext of ContextImpl. newActivity of Instrumentation returned an Activity instance.
LoadedApk.makeApplication can obtain the current application. If it does not exist, create a new application. Finally, through ContextImpl Setoutercontext and the attach method of Activity to associate the ContextImpl instance with the Activity instance.
use
Custom Application
Create a new MyApplication class, which inherits from Application
import android.app.Application; import android.content.Context; public class MyApplication extends Application { private static Context context; public static Context getMyContext() { return context; } @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); } }
Use MyApplication in Manifest;
<application android:name="com.rust.aboutview.MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> ......
You can call the getMyContext() method in different places
MyApplication.getMyContext()