Welcome to my personal website: https://coderyuan.com
Context is a concept that is used a lot in Android App, and it is often translated into context. This concept is also used in other technologies. If you accidentally click on the source code of Context, then let’s analyze and analyze Context in Android. What is it?
Paste the code first
/**
* Interface to global information about an application environment. This is
* an abstract class whose implementation is provided by
* the Android system. It
* allows access to application-specific resources and classes, as well as
* up-calls for application-level operations such as launching activities,
* broadcasting and receiving intents, etc.
*/
public abstract class Context {
It can be seen from the comments that the official Android interpretation of it can be roughly understood as an interface for global information in the application environment . It integrates many system-level services, which can be used to obtain classes and resources in applications, and can be used for applications. Program-level call-up operations, such as starting Activity, Service, etc., and the Context class is abstract and does not contain specific function implementations.
That means that you can do a lot of things, anyway, it's very arrogant. . .
So I searched for the reference of Context, no more.
Structural Analysis
The Context class contains two types of content: constants , abstract method definitions
Since Context itself is abstract, it is only responsible for defining the required operations, and it does not care about the specific implementation. Although the ContextWrapper that directly inherits from Context is not modified with abstract, it does not do the actual implementation, but just does a simple The packaging for better presentation to classes such as Application and Service. What we can see is the first layer of Context implementation, which should be ContextImpl located under the android.app package
So first analyze the member variables in ContextImpl (including static, final, public, private), the following source code is all the member variables of ContextImpl:
// ContextImpl.java
/**
* Map from package name, to preference name, to cached preferences.
*/
@GuardedBy("ContextImpl.class")
private static ArrayMap<String, ArrayMap<File, SharedPreferencesImpl>> sSharedPrefsCache;
/**
* Map from preference name to generated path.
*/
@GuardedBy("ContextImpl.class")
private ArrayMap<String, File> mSharedPrefsPaths;
final @NonNull ActivityThread mMainThread;
final @NonNull LoadedApk mPackageInfo;
private @Nullable ClassLoader mClassLoader;
private final @Nullable IBinder mActivityToken;
private final @Nullable UserHandle mUser;
private final ApplicationContentResolver mContentResolver;
private final String mBasePackageName;
private final String mOpPackageName;
private final @NonNull ResourcesManager mResourcesManager;
private @NonNull Resources mResources;
private @Nullable Display mDisplay; // may be null if default display
private final int mFlags;
private Context mOuterContext;
private int mThemeResource = 0;
private Resources.Theme mTheme = null;
private PackageManager mPackageManager;
private Context mReceiverRestrictedContext = null;
// The name of the split this Context is representing. May be null.
private @Nullable String mSplitName = null;
private final Object mSync = new Object();
@GuardedBy("mSync")
private File mDatabasesDir;
@GuardedBy("mSync")
private File mPreferencesDir;
@GuardedBy("mSync")
private File mFilesDir;
@GuardedBy("mSync")
private File mNoBackupFilesDir;
@GuardedBy("mSync")
private File mCacheDir;
@GuardedBy("mSync")
private File mCodeCacheDir;
// The system service cache for the system services that are cached per-ContextImpl.
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
According to its name and type, the basic role can be analyzed:
sSharedPrefsCache : Cache information for managing SharedPreference
mSharedPrefsPaths : used to save SharedPreference file storage paths
mMainThread : The main thread used to operate components such as Activity
mPackageInfo : PackageInfo of the currently loaded APK, including package name, version number, etc.
mClassLoader : The class loader used to load Dex classes, similar to the ClassLoader in other Java projects, it will be used when doing plug-in in Android
mActivityToken : a Binder that can be used for IPC communication
mUser : used to manage user data, used with ContentResovler
mContentResolver : Application-level ContentResolver for data exchange between different processes
mBasePackageName : base package name
mOpPackageName : It seems to be another package name. . .
mResourcesManager : System resource service, which can be used to obtain resources such as pictures and strings, and is used a lot
mResources : System resources, such as themes, color definitions, etc.
mDisplay : System monitor/screen information, such as getting resolution, PPI
mFlags : Flag bit, used to distinguish the category of Context
mOuterContext : Context used externally
mThemeResource : Theme resource Id
mTheme : The theme used by the APP
mPackageManager : Package manager, which can be used to obtain information about the installed APP
mReceiverRestrictedContext : should be the Context used for BroadcastReceiver
mSplitName : It is speculated that it is also used to distinguish Context
mSync : used to set the synchronization function to ensure the thread safety of file operations
mDatabasesDir : Directory path to store database files
mPreferencesDir : Directory path to store SharedPreference files
mFilesDir : directory path for storing general files
mNoBackupFilesDir : Directory path to store files not used for automatic backups
mCacheDir : Directory path to store cache files
mCodeCacheDir : The directory path to store code cache files (mainly used to load Dex)
Among them, the @GuardedBy annotation is used to deal with multi-threaded protection issues, to indicate which object is protected by a synchronization lock in a multi-threaded environment
After analyzing the use of the above member variables, the basic responsibilities of ContextImpl are also clarified. The remaining member methods and static methods are all operations based on these members, that is, some operations that we are familiar with Context can perform, such as: startActivity, startService, getExternalCacheDir, getDatabasesDir, getMainLooper, getResources, getTheme, checkPermission, etc.
However, in addition to these member methods, there are several static methods that are important:
createSystemContext、createSystemUiContext、createAppContext、createActivityContext
Although I haven't seen any direct references to these methods, take the Activity startup process as an example. ActivityManagerService (AMS) uses the zygote process to start an ActivityThread first. When attaching, it will call the static method of ContextImpl to create all The required Context is also the same for the Context in other components such as Application and Service. Therefore, the various Contexts we use in the App are actually created by ContextImpl in the final analysis, which shows the importance of ContextImpl!
Context memory leak
As we all know, memory leaks in Android are caused by Context in many cases. According to the above analysis of its structure and use, the following reasons can be inferred:
Involving various systems and APP resources, the function is too powerful, resulting in too many places of use, causing confusion in the process and reference relationship, such as: asynchronous network requests, View animations, etc., are not handled properly in the process, resulting in failure to release
Disorganized value transfer makes many objects hold a Context, which opens up too many resources that cannot be recycled
Drawable objects and Bitmap objects are not recycled in a timely manner, and even bound to View
The abuse of singleton causes Context to be referenced for a long time and cannot be released
solution:
When there is no need to pass values, try to use the Context of the Application, so as to ensure that the Context can be used globally without creating multiple copies.
In the case of coupling with components such as Activity, when it is necessary to use the Context of the Activity, consider using weak references to avoid cyclically holding the Context
Summarize
In general, Context in Android is the encapsulation of a series of system service interfaces, including: management of internal resources, packages, class loading, I/O operations, permissions, main threads, IPC, and component startup. Its structure is relatively simple, but there are many methods and operations involved. When using it, special attention should be paid to memory leaks and multi-threading problems to avoid conflicts or serious bugs.