The application I'm working on is a memory leak. As far as I can tell, I am doing everything that was suggested in: http://developer.android.com/resources/articles/avoiding-memory-leaks.html
I turned off the application to a very simple application that does nothing but set the background image. Each time I change the orientation of the screen, the application loses 30 to 50 thousand. Memory.
Therefore, I am suspicious of the following:
SetContentView () as well as findViewById ()
Do I need to do something in onDestroy () associated with these calls to separate them from Activity?
I also have a couple of questions. In onDestroy (), I call setBackgroundResource (0). I believe that if I do not, then Drawable for the background bitmap will support a callback for the view, and this will leak the entire context. It's true? Adding this call to onDestroy () certainly showed a big difference in the amount of leaks. In view constructors, I try to remove some activity references by making super () calls with the application context, as opposed to the activity context. Does this really provide this benefit or does it really matter? Are there any side effects for this that I should know about?
Code and XML follows: At the moment, I really don't understand why this should be a memory leak. Any enlightenment would be greatly appreciated.
Memleak.java
package randombrand.MemLeak;
import randombrand.MemLeak.R;
import randombrand.MemLeak.MLView;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MemLeak extends Activity {
private MLView mmlView;
private static final String strmlBundle = "Mem Leak";
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.memleak_layout);
mmlView = (MLView) findViewById(R.id.viewMemLeak);
try {
mmlView.Init(this);
SetBackgroundBitmap();
} catch (Exception ex) {
Log.e(strmlBundle, "Failed to launch Mem Leak." + ex);
this.finish();
}
if (icicle == null) {
mmlView.SetActive(true);
} else {
Bundle bundle = icicle.getBundle(strmlBundle);
if (bundle != null) {
mmlView.SetActive(true);
mmlView.invalidate();
} else {
mmlView.SetActive(false);
}
}
}
@Override
protected void onPause() {
super.onPause();
mmlView.SetActive(false);
}
@Override
protected void onResume() {
super.onResume();
mmlView.SetActive(true);
}
private void SetBackgroundBitmap() {
mmlView.setBackgroundResource(R.drawable.dark_background);
}
@Override
public void onDestroy() {
super.onDestroy();
mmlView.setBackgroundResource(0);
}
}
MLView.java
package randombrand.MemLeak;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
public class MLView extends View {
private static final long ltFpDrawDelay = 66;
Context mContextApp;
private boolean mfActive = false;
public MLView(Context context, AttributeSet aSet) {
super(context.getApplicationContext(), aSet);
}
public MLView(Context context, AttributeSet aSet, int nStyle) {
super(context.getApplicationContext(), aSet, nStyle);
}
public void Init(MemLeak mLeak) {
mContextApp = mLeak.getApplicationContext();
SetActive(true);
}
public void Update() {
mRedrawHandler.sleep(ltFpDrawDelay);
}
public void SetActive(boolean fActive) {
mfActive = fActive;
if (fActive) Update();
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
private RedrawHandler mRedrawHandler = new RedrawHandler();
class RedrawHandler extends Handler {
@Override
public void handleMessage(Message msg) {
MLView.this.Update();
MLView.this.invalidate();
}
public void sleep(long ltMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), ltMillis);
}
}
}
memleak_layout.java
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<randombrand.MemLeak.MLView
android:id="@+id/viewMemLeak"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="randombrand.MemLeak"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="5" />
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:debuggable="true">
<activity android:name="MemLeak"
android:launchMode="singleInstance"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>