In the statement Android we often encounter this situation, in the creation of an object often need to pass a This parameter, such as: statement MyView MView = new MyView (this), required to pass a This parameter, this is what it refers to? In fact, this refers to the current activity.this, which is the activity of this statement. Activity.this is the context of this activity, then what is this context? What role does it play?
The context is literally " contextual ", which is located in the Android.content.Context of the framework package, which is actually a long type, similar to a handle. Many methods require a context to identify the caller's instance.
The context provides an interface for global information about the application environment. It is an abstract class, and its execution is provided by the Android system. It allows you to get the resources and types that are characterized by the app. Start an application-level operation at the same time, such as starting an activity, sending a broadcast, accepting intent
The context inheritance relationship is as follows:
There are two types of context
context can do a lot of things in Android , but the main function is to load and access resources. There are two kinds of contextin Android , one is application contextand the other is activity context.
Add:
Getapplicationcontext () Returns the context of the application, the life cycle is the entire application, and the application destroys it before it destroys
The context of the Activity.this returns the current activity, belonging to the activity, destroying the activity and destroying it.
Getbasecontext () Returns the context that is set by the constructor or Setbasecontext (), and is generally not commonly used.
(1) Activity context
Usually we pass the activity contextbetween various classes and methods. Like an activity oncreate.
protected void OnCreate (Bundle state) { Super.oncreate (state);
TextView label = new TextView (this); Pass context to view control
Label.settext ("Leaks is bad");
Setcontentview (label); } |
Passing the activity context to view means that view has a reference to activity that references the resources that the activity occupies: view hierachy, Resource, and so on.
Memory leaks
If a memory leak occurs in the context , it will leak a lot of memory. The leak here means that the GC has no way to reclaim the activity's memory.
NOTE: The GC does not have the means to reclaim the appropriate memory, and the personal feeling is that the pass-through Context increases the reference count of the object pointer, so GC based on smart pointer technology cannot release the corresponding memory.
When the screen rotates, the system destroys the current activity, saves the state information, and then creates a new one. For example, we wrote an application that needed to load a large picture, and we didn't want to destroy the image every time we rotated the screen, reload it. The simple idea to implement this requirement is to define a static drawable so that the activity class is created and destroyed it is always stored in memory. Implementations similar to:
Public classMyActivityextendsActivity {Private Staticdrawable Sbackground;protected voidonCreate (Bundle state) {Super. OnCreate (state); TextView label=NewTextView ( This); Label.settext ("Leaks is bad"); if(Sbackground = =NULL) {Sbackground=getdrawable (R.DRAWABLE.LARGE_BITMAP);} Label.setbackgrounddrawable (sbackground);//drawable attached to a viewSetcontentview (label);}}
The program looks simple, but it's a big problem. There is a leak when the screen rotates (that is, the GC cannot destroy the activity). As we have just said, the system destroys the current activity when the screen is rotated. However, when drawable is associated with a view, Drawable saves the view's reference, that is, Sbackground holds a reference to the label, and the label holds the activity's reference. Since drawable cannot be destroyed, neither the reference nor the indirect reference can be destroyed, so that the system has no way to destroy the current activity, resulting in a memory leak. The GC is powerless against this type of memory leak. The way to avoid this kind of memory leak is to avoid the life cycle of any object in the activity and avoid the activity being destroyed by the object's reference to activity.
To prevent memory leaks, we should pay attention to the following points:
- Do not allow objects with long life cycles to refer to the activity context, that is, to ensure that the object referencing the activity is the same as the activity itself life cycle
- For objects with long life cycles, you can use the application context
- Avoid non-static inner classes, use static classes as much as possible, avoid life cycle problems, and notice life-cycle changes caused by internal classes to external object references
when to create a context instance
Having become familiar with the context's inheritance, we then analyze what situations the application needs to create a context object for? Application to create a context instance of the
There are several situations where:
1. When creating application objects, and the entire app has a application object
2. When creating service objects
3. When you create an Activity object
So the number of context formulas common to the app app is:
Total number of context instances = Number of Service + activity + 1 (application corresponding context instance)
the opportunity to create a context specifically
1. Time to create application objects
The first time each application starts, the Application object is created first. If an activity (startactivity) process comparison is initiated on the application
Clearly, the time to create the application in the Create Handlebindapplication () method, the function is in the Activitythread.java class, as follows:
1 //CONTEXTIML instances created at the same time when creating application2 Private Final voidhandlebindapplication (appbinddata data) {3 ... ..4 ///Create Application Object5Application app = Data.info.makeApplication (Data.restrictedbackupmode,NULL);6 ... ..7 }8 PublicApplication Makeapplication (BooleanForcedefaultappclass, instrumentation instrumentation) {9 ... ..Ten Try { OneJava.lang.ClassLoader cl =getClassLoader (); AContextimpl AppContext =NewContextimpl ();//Create a Contextimpl object instance -Appcontext.init ( This,NULL, Mactivitythread);//initialize the related properties of the CONTEXTIML instance - ///Create a new Application object theApp =MActivityThread.mInstrumentation.newApplication ( - cl, Appclass, appContext); -Appcontext.setoutercontext (APP);//Pass the application instance to the Contextimpl instance - } + ... .. -}
2. Time to create Activity objects
When an activity is started by startactivity () or Startactivityforresult () request, if the system detects that a new activity object needs to be created, it
Callback Handlelaunchactivity () method, which then calls the Performlaunchactivity () method to create an activity instance, and callback
OnCreate (), OnStart () methods, and so on, functions are located in the Activitythread.java class, as follows:
//Create a CONTEXTIML instance while creating an activity instancePrivate Final voidhandlelaunchactivity (Activityrecord R, Intent customintent) {... Activity a= Performlaunchactivity (R, Customintent);//Start an activity}Private FinalActivity performlaunchactivity (Activityrecord R, Intent customintent) {... Activity Activity=NULL; Try { //Create an Activity object instanceJava.lang.ClassLoader cl =R.packageinfo.getclassloader (); Activity=minstrumentation.newactivity (cl, Component.getclassname (), r.intent); } if(Activity! =NULL) {Contextimpl AppContext=NewContextimpl ();//Create an Activity instanceAppcontext.init (R.packageinfo, R.token, This);//initialize the related properties of the CONTEXTIML instanceAppcontext.setoutercontext (activity);//Pass the activity information to the Contextimpl instance...} ...}
3. Time to create service objects
With StartService or Bindservice, if the system detects that a new service instance needs to be created, it will callback the Handlecreateservice () method,
Complete the relevant data operation. The Handlecreateservice () function is located in the Activitythread.java class, as follows:
//Create a CONTEXTIML instance while creating a service instancePrivate Final voidHandlecreateservice (createservicedata data) {...//Create a service instanceService service =NULL; Try{Java.lang.ClassLoader cl=Packageinfo.getclassloader (); Service=(Service) Cl.loadclass (data.info.name). newinstance (); } Catch(Exception e) {} ... Contextimpl Context=NewContextimpl ();//Create a Contextimpl object instanceContext.init (PackageInfo,NULL, This);//initialize the related properties of the CONTEXTIML instance//get the Application object information we created earlierApplication app = Packageinfo.makeapplication (false, minstrumentation); //Pass the service information to the Contextimpl instanceContext.setoutercontext (service); ...}
In addition, it is important to emphasize that, through the analysis of Contextimp, most of the operations of its methods are directly calling its property mpackageinfo (the attribute class
Type PackageInfo). This shows that Contextimp is a lightweight class, and PackageInfo is the real heavyweight class . And the one in the app
All CONTEXTIML instances correspond to the same PackageInfo object.
(2) Application context
life cycle: The application context life cycle is long and exists with the existence of an application, regardless of the activity's life cycle.
Get: Application Context can be obtained through the context. Getapplicationcontext or Activity.getapplication method.
Java usually uses a static variable (such as singleton) to synchronize the state between activity (between classes in the program). In Android It is more plausible to use application context to correlate these states.
Each activity is a contextthat contains the state of the runtime. Similarly application also has a context,Android will ensure that the context is the only instance.
Make your own application context needs to inherit Android. App. Application, then explain this class in the app's manifest. Android will automatically help you create instances of your class, and then you can use the Context. Getapplicationcontext () method to get the application in each activity. The context .
classMyAppextendsApplication {PrivateString MyState; PublicString getState () {returnMyState; } Public voidsetState (String s) {MyState=s; }}classBlahextendsActivity {@Override Public voidonCreate (Bundle b) {... MYAPP appState=( MyApp) Getapplicationcontext ()); String State=appstate.getstate (); ... }}
Summary and usage of context in Android