Memory leak in a very simple application

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;
    // true when we are not sleeping in the background
    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>
+3
1

jbww,

,

android:configChanges="keyboardHidden|orientation"

Activity AndroidManifest.xml, , onConfigurationChanged().

, .

, .

+1

All Articles