В приложении, над которым я работаю, происходит утечка памяти.Насколько я могу судить, я делаю все, что предлагается в: http://developer.android.com/resources/articles/avoiding-memory-leaks.html
Я сократил свое приложение до очень простого приложения, которое ничего не делает, кроме установки фонового изображения.Каждый раз, когда я изменяю ориентацию экрана, приложение пропускает 30–50 Кбайт памяти.
Поэтому я подозреваю следующее:
SetContentView () и findViewById ()
Нужно ли что-то делать в onDestroy () для этих вызовов, чтобы отделить их от действия?
Также у меня есть пара вопросов.В onDestroy () я вызываю setBackgroundResource (0).Я полагаю, что если я этого не сделаю, Drawable для фонового растрового изображения будет поддерживать обратный вызов для представления, и это вызовет утечку всего контекста.Это правда?Добавление этого вызова в onDestroy (), безусловно, сильно повлияло на величину утечек.В конструкторах представлений я пытаюсь удалить некоторые ссылки на действие, совершая вызовы 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>