This article was first published on my wechat official account Android_De_Home. Please scan the following QR code to follow the wechat public for more knowledge. This article is a sydMobile original article, can be reproduced at will, but be sure to cite the source!

If you’ve ever written a Java program, when you’re developing a Java program, the entry is in the main() method, and you just start writing your program in the main() method, you just create any class you want, but in Android development, Have you seen new Activity(), new Service()? No, these components in Android are not like normal Java objects where you can just create an instance and then call the corresponding method, and that’s where Android is different from normal Java development, because Android defines an environment for you, These components run in this environment and have their own life cycle, which is defined in the Android system. This is the environment of the Android system, and the most important thing in this environment is the Context.

The official introduction of Context

This is the introduction to the Android developer website about the Context, a very simple introduction. Connected to global information about the application, this is an abstract class implemented through the Android system that allows access to application-specific resources and classes, as well as application-level operations (such as launch activities, broadcast and accept intents, and so on). It allows access to resource types that are specific to the current application. It is a resource that holds some resources (system-level, such as access to resource bundle contents, images, getSystemService, etc.). The Android system provides a ContextImpl (ContextImpl) for the abstract class. It allows you to access the application’s resources and classes (including the most common ones such as starting an Activity, broadcasting, etc.). Such description is still very abstract ah, slowly look down.

Let’s look at the Context class inheritance

This abstract introduction may not be easy to understand, but let me give you an example (it may be a little inappropriate, but it will be easy to understand) :

Through the INTRODUCTION of the Context by the API, we can know that it holds the global information of the application, through which we can access the resources and classes that use the application. If you think of the Android system as a company, then the Context can be thought of as the owner of the company directly controlling the resources of the company, Application, Activity, Service and other subclasses of the Context, all of which are the employees that the owner is looking for. They have a boss who assigns them specific work hours and hours (corresponding to their life cycle), and these employees are not randomly hired because they need to be assigned specific work tasks by the system (i.e., the company), so they can’t be randomly hired like other employees. TextView, View and so on can be seen as the supplies needed by these main employees when they work (such as books, desks, computers, mice and other work AIDS). Relatively speaking, they can be made randomly according to the required functions, and a new one can be needed (equivalent to buying one randomly in the market). All these employees can finish their work (develop an APP) only under the leadership of the boss and with the resources of the company. Chestnuts like this should be more graphic.

So let me just draw a little Context inheritance diagram just to make it easier to understand

Of course, this is just to highlight the classes that we use, the direct and indirect subclasses of Context. ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl: ContextImpl

ContextImpl does not exist as a public class, but as a class that inherits the Context. This file is a protected file, which is annotated as an internal protected file, so we do not display it in the IDE, you can view it in the source.

ContextImpl class:

ContextImpl is a common implementation of the Context API, which provides basic Context objects for activities and other application components.

ContextWrapper: ContextWrapper

The ContextWrapper class proxies the implementation of a Context, simply delegating all of its calls to another Context object (ContextImpl), and can be classified as modifying behavior without changing the class of the original Context, which is the Context class modifying class. The inside of the real implementation class is ContextImpl ContextWrapper method call is invoked ContextImpl method.

ContextThemeWrapper

It is an encapsulated class with a theme, more themes than ContextWrapper, and one of its direct subclasses is Activity.

By combining the Context inheritance diagram with several familiar classes in development, Activity, Service, and Application, we can think of Context as having three types. Application, Activity, and Service, each of which has different roles, belong to the Context, and their context-owning functions are implemented by the ContextImpl class.

The function of the Context

Context as the running environment of an application, it has a lot of functions, such as popping up a Toast, starting an Activity, starting a Service, sending a broadcast, operating a database, retrieving resource files, and many more. Since the specific capabilities of the Context are implemented by the ContextImpl class, Activity, Service, and Application contexts are common in most cases, but there are a few special scenarios, such as starting an Activity, At this time, due to security and other reasons, Android does not allow an Activity or Dialog to appear out of thin air. The start of an Activity must be built on the basis of another Activity, that is, the return stack formed on this basis. A Dialog must pop up on top of an Activity (unless it’s a System Alert Dialog), so in this scenario we can only use an Activity-type Context, otherwise we’ll get an error. It is possible to start an Activity using an Application Context, but this is not recommended because of stack issues.

The Context number

The number of contexts in an Application can be counted as follows: Number of contexts = Number of Activities + Number of Services + 1 (Number of Applications)

Note the number of applications in the multi-process state. Some people on the web say that several processes produce several Application instances, but by typing the address of getApplicationContext, I find that the address of the Application is the same in different processes. So I think in a multi-process, the Application is still one, but in a new process it will call onCreate () again to instantiate it.)

Let’s look at each of these types of Context

Design of the Application Context

The Application class is also very common, translated as the Application, first let’s look at the Application Android source code is how to introduce.

The base class that maintains the global Application state, you can create your own Application class by inheriting Application. This class is for Android in AndroidMainfest.xml: Name property, and this class is instantiated before any other class is instantiated, in other words the Application class is instantiated first when we open the Application, Application is singleton, it gives you a lot of methods in some modular way, If your singleton pattern requires a global Context (such as when registering broadcast Receive) include getApplicationContext () as an argument to call your singleton’s getInstance method. To test the code, let’s create a new Application inheriting Application and declare it in the androidMainfest.xml file.

So when we launch our APP the Android system will first create a MyApplication for us how do we get our Application instance in our code? It’s pretty simple. The Android API gives me the getApplication method to get it

Now that we have our Application object instance, let’s look at the print:

This is the result printed in MainActivity. It’s not exciting, so LET’s put in all the methods that have to do with Context, and let’s see what happens.

First shows the processes in this program, because at the time of startup ActivitySecond launched a new process, that is to say ActivitySecond belongs to com. Syd. Mystudydemo: second the process. The result: getApplication and getApplicationContext get the same result no matter in which Activity or in different processes. The corresponding object is MyApplicaton, but it is important to note that in different processes, MyApplication will call onCreate again when a new process is started. This is something to be aware of (it is possible that variables in Application may be assigned different values in different processes).

So what’s the difference between getApplication and getApplicationContext? These two methods are in different classes, so getApplicationContext is a little bit more scoped, it’s a method inside the Context, and getApplication is a method inside the Activity. That is, any Context object can get the Context object through getApplicationContext, whereas getApplication is only available in the Activity object.

The getApplicationContext API makes it clear that it takes an Application object of the current process, and it should be used in this case, Use registerReceive (Br) if you want the Context object to be separated from the current Context lifecycle (i.e. the Application lifecycle obtained using getApplicationContext is not related to the current component, but to the current process) OadcastReceiver IntentFilter), for example. If you register a receive with a Context from an Activity, the receiver is within the scope of the Activity. This means that you need to unregister the Activity before it is destroyed. In fact, if you don’t, Android will clear your leaked registration, remove the Activity, and log an error message. Therefore, if you use the Activity context to register a static receiver (global to the process, not associated with an Activity instance), your registration will be deleted at any point where the Activity you are using is destroyed. If you use the Context returned by the getApplicationContext method, the Receiver is registered in the global state associated with your Application. So it will never be unregistered by the system. This is necessary when the receiver is related to static data rather than a particular component. However using getApplicationContext in other places is very easy to leak memory if you forget unregister, unbind, etc.

So we know that using getApplicationContext to get the Context is not related to a specific component, but it is related to your entire process, the scope is very large, but if you use it without conditions, it can easily cause memory leaks.

Returns the underlying context object, setting the value of the context through the constructor or setBaseContext. So the context object that we’re getting is the ContextImpl object, the implementation of the abstract context, and all the methods in the context are going to be done inside the ContextImpl, The types of Context such as Application, Activity, and Service do not implement the methods in the Context; they implement the methods in the ContextImpl called. ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper, ContextWrapper

MBase. Method () is the ContextWrapper object that calls the mBase method.

We can look at this method

In fact, mBase is always assigned by this method, and this method is called automatically by the system, before onCreate. We need to know that system components such as Application, Activity, and Service are not created by constructors new, but by system calls. We can think of Application as an Application object generated by the Android system after onCreate (singleton, onCreate is not called repeatedly, except in multiple processes).

Conclusion:

Context, as the running environment of an application, has many functions. Methods such as popping up a Toast, starting an Activity, starting a Service, sending a broadcast, operating a database, obtaining resource files, and so on are all in Context.

For example, our common method: GetResources (), getPackageManager (), getContentResolver (), getApplicationContext (), getColor (), getDrawable (), obtainStyledAttributes(),getPackageName(),getPackageResourcePath(),getSharedPreferences(),deleteFile(),getExternalCacheD Ir () and so on, you can think of it this way, the Context is the environment in which the APP that we’re writing on the Android system is going to run, it’s going to hold the resources that the APP is going to run, All of these resource methods related to our APP are inside the Context (so we can use them in all of the subclasses of Context), There are only very specific methods in a specific component such as an Activity that is page-specific so the window methods are in the Activity (getWindowsManager() and so on). Context, as the operating environment of Android applications, is customized by Android system, so we don’t need to generate its subclasses by new, even if you use new to generate, that will only generate ordinary objects, not components in Android system, it is not given a life cycle by the system, So it doesn’t have any value. To have an understanding of the operating environment of the Android system, our App is run in a Context environment, and these components are customized by the system and given a life cycle in the environment, which is different from Java.