android basic tutorial on the use of context

  • 2020-05-26 10:05:06
  • OfStack

There are two types of context in android, one is application context, one is activity context, and usually we pass activity context between the various classes and methods.

Distinction and connection:


public class MyActivity extends Activity {
    public void method() {
       mContext = this;    // since Activity extends Context
       mContext = getApplicationContext();
       mContext = getBaseContext();
    }
 }

this is an instance of Activity, extending Context, whose lifecycle is Activity created to destroy
getApplicationContext() returns the context of the application, and the lifecycle is the entire application, which is destroyed by the application
Activity.this context returns the current activity context, belonging to activity, activity destroys it
getBaseContext() returns the context specified by the constructor or set by setBaseContext(). SDK is poorly documented and not recommended
If you understand the life cycle, you will make mistakes in the process of use. For example, if there is a global data operation class that USES context, you will use getApplicationContext instead of ACtivity. This ensures that the operation of the database is independent of activity (no 1 will directly refer to Activity's resources to prevent memory leak).

Application scenarios:
For example, one activity onCreate:


protected void onCreate(Bundle state) {        
     super.onCreate(state);        
     TextView label = new TextView(this); // pass context to view control        
     label.setText("Leaks are bad");        
     setContentView(label);
}

Passing activity context to view means that view has a reference to activity, which in turn refers to resources owned by activity: view hierachy, resource, etc.
So if you have an context memory leak, you're going to leak a lot of memory. The leak here means that gc has no way to reclaim activity's memory.

Leaking an entire activity is the easy one. When the screen rotates, the system will destroy the current activity, save the status information, and create a new activity.
For example, if we write an application that needs to load a large image, we don't want to destroy the image and reload it every time we rotate the screen.
The simple idea to implement this requirement is to define a static Drawable so that the Activity class is created and destroyed and is always kept in memory.
Implementation example:


public class myactivity extends Activity {        
       private static Drawable sBackground;        
       protected void onCreate(Bundle state) {               
              super.onCreate(state);                
              TextView label = new TextView(this);             
              label.setText("Leaks are bad");                
              if (sBackground == null) {                        
                        sBackground = getDrawable(R.drawable.large_bitmap);                
              }        
              label.setBackgroundDrawable(sBackground);//drawable attached to a view        
              setContentView(label);        
       }
}

This program looks simple, but it is very problematic. There is leak when the screen is rotated (that is, gc cannot destroy activity).
As we said earlier, the system destroys the current activity as the screen rotates. But when drawable is associated with view, drawable saves the reference of view, sBackground saves the label reference, and label saves the activity reference.
Since drawable cannot be destroyed, its references and indirect references cannot be destroyed, so 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 memory leak is to avoid any object in activity having a longer lifetime than activity and activity not being destroyed due to the object's reference to activity.
We can use application context.
application context accompanies the birth of application and has nothing to do with the life cycle of activity.
application context can be obtained by the Context.getApplicationContext () or Activity.getApplicationContext () method.

To avoid memory leaks associated with context, keep the following in mind:
1. Do not let long-lived objects reference activity context, that is, make sure that the object referencing activity is the same as activity itself
2. For long-lived objects, application context can be used
3. Avoid non-static inner class, use static class as much as possible, avoid the life cycle problem, and pay attention to the life cycle change caused by the reference of inner class to external object


Related articles: