I just read a blogpost by Romain Guy on how to avoid memory leaks in Android.
In the article he gives this example:
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);
}
Romain said:
This example is one of the simplest cases of leaking the Context.
My question is, how do you modify it correctly?
Just like this?
TextView label = new TextView(Context.getApplicationContext());
I tested both ways and the results are the same. I can’t locate the difference. And I think that this is more correct than the Application context. Because this is a reference to Activity, that is to say, the TextView belongs to that Activity.
Could someone give me an explanation for this?
The actual problem with that code isn’t the context passed to create the drawable, but private static Drawable sBackground;
The static Drawable is created with the Activity as the context, so in THAT case, there’s a static reference to a Drawable that references the Activity, and that’s why there’s a leak. As long as that reference exists, the Activity will be kept in memory, leaking all of its views.
So it’s the Drawable which should be created using the application context, not the TextView. Creating the TextView with “this” is perfectly fine.
edit : Actually, that might not make a big difference, the problem is that once the drawable is binded to a view, there’s a reference to the view, which references the activity. So you need to “unbind” the drawable when you exit the activity.