Android apps are limited to up to 16m of RAM, at least for T-mobile G1 (hundreds of trillion of memory is now available, of course). It includes two parts that the phone itself occupies and the developer can use. Even if you're not using all of your memory, you should try to use as little memory as possible, lest other applications turn off your application while it is running. The more applications that Android can keep in memory, the faster users will be switching applications. As part of my work, I've studied the memory leaks of Android apps, most of which are caused by the same error, which is to keep a long reference to a context.
In Android, contexts (context) are used in many operations, but most are load and access resources. This is where all the widgets will accept a context parameter in their constructor. In a qualified Android application, you can usually use two contexts: Activity and Application (application). Activities (activity) are usually passed to classes or methods that require context parameters:
Copy Code code as follows:
@Override
protected void OnCreate (Bundle state) {
Super.oncreate (state);
TextView label = new TextView (this);
Label.settext ("Leaks are bad");
Setcontentview (label);
}
This means that the view has a reference to the activity as a whole and holds references to all the objects held in the activity (activities), usually including the entire view hierarchy and all its resources. Therefore, if you "leak" the context (where the "leak" means that you keep a reference and organize GC to collect it), you will cause a lot of memory leaks. If you're not careful, "leaking" an entire activity is a very simple matter.
When the direction of the screen changes, the system destroys the current activity by default and creates a new one and keeps its state. The result is that Android will reload the application UI from the resource. Now imagine that you've written an application that has a very large bitmap, and you don't want to reload each time you rotate. The easiest way to keep it and rotate it without reloading is to save it on a static field:
Copy Code code as follows:
private static drawable Sbackground;
@Override
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);
Setcontentview (label);
}
This code is very fast, but also wrong enough. It leaks the first activity that was created when the first screen angle was changed. When a drawable is attached to a view, this view is set to a callback for the drawable. In the code snippet above, this means that the drawable has a reference to TextView, and the TextView keeps a reference to the activity (the context object). The activity also has references to many objects (this depends on your code).
This example is one of the simplest reasons for a context leak, and you can look at the problem by looking at our main screen source (view Unbinddrawables () method) by setting the drawable callback that was saved when the activity was destroyed. More interestingly, you can create a context-leaking chain, which is, of course, very bad. They allow you to run out of memory quickly.
There are two simple ways to avoid the memory leaks associated with the context. The most obvious one is to avoid using it outside of the context itself. The example above shows a static reference within a class and an indirect reference to an external class that is very dangerous. The second solution is to use the application context. This context will exist with your application and is independent of the life cycle of the activity. If you plan to keep an object that requires a long lifecycle for the context, remember to consider the Application object. You can get it very conveniently by calling Context.getapplicationcontext () or activity.getapplication ().
In short, to avoid memory leaks involving the context, keep in mind the following points:
1. Do not maintain a long life cycle reference to an activity context (a reference to an activity should be the same as the activity's own lifecycle)
2. Attempt to use the application context (context-application) instead of the active context (context-activity)
3. If you cannot control their lifecycle, avoid the use of static internal classes in activities (activity), use static classes, and use weak references to the interior of an activity. The solution to this problem is to use an external class with a static inner class and a weak reference (WeakReference). Just like Viewroot and its W inner class.
4. The garbage collector is not hundred percent insured for memory leaks.