我正在工作的應用程序泄漏內存。據我所知,我正在做的一切建議在:http://developer.android.com/resources/articles/avoiding-memory-leaks.html內存泄漏非常簡單的應用程序
我已經削減我的應用程序下降到一個非常簡單的應用程序,什麼都不做,但設置背景圖像。每次我進行屏幕方向更改時,應用程序都會泄漏30k-50k的內存。
所以我懷疑如下:
的setContentView() 和 findViewById()
我需要做的東西在的onDestroy()有關這些調用,從去耦活動?
另外我有幾個問題。在onDestroy()我調用setBackgroundResource(0)。我相信如果我不這樣做,背景位圖的Drawable將保持對視圖的回調,這會導致整個上下文的泄漏。這是真的?將這個調用添加到onDestroy()當然似乎對泄漏的大小有很大的影響。在視圖構造函數中,我嘗試通過使用Application上下文進行super()調用,而不是活動上下文來移除對活動的一些引用。這實際上是否提供這種好處,或者它有什麼關係?是否有這樣的副作用,我應該知道?
代碼和XML如下:在這一點上,我真的不明白爲什麼它應該泄漏內存。任何啓發將不勝感激。
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>
請仔細閱讀前面的問題,並通過選中旁邊的複選框將最佳答案標記爲正確答案。 – 2011-03-18 19:11:54
我知道這是一個古老的問題,但會取消onDestroy幫助中的視圖?如在'mmlView = null;'中。你爲什麼在你的視圖中使用'context.getApplicationContext()'?一定是這樣嗎? – 2013-11-25 14:52:02