Освободить память от конкретной деятельности, когда она уничтожена
У меня есть пусковая установка Activity
, которая загружает и изменяет размер большого растрового изображения при его открытии.
Всякий раз, когда вы нажимаете кнопку "Назад", Activity
имеет значение destroyed
. Но я думаю, что память еще не выпущена.
Когда я открываю приложение, нажмите кнопку "Назад" и снова откройте его (повторно), я получу OutOfMemoryError
.
Прошу прощения за этот вопрос новичку, но мне интересно, как как освободить память всякий раз, когда Activity
есть destroyed
?
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
//MARK - movingBackgroundImageView
movingBackgroundImageView = (ImageView) findViewById(R.id.movingBackgroundImageView);
movingBackgroundImageView.setColorFilter(Color.argb(255, 255, 255, 255));
movingBackgroundImageView.setScaleType(ImageView.ScaleType.MATRIX);
movingBackgroundImageView.setAlpha(0.28f);
prepareBackgroundAnimation();
}
private void prepareBackgroundAnimation() {
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
screenWidth = displaymetrics.widthPixels;
screenHeight = displaymetrics.heightPixels;
movingImageHeight = displaymetrics.heightPixels;
movingImageWidth = 1920.0 / 1080.0 * movingImageHeight;
bitmapImage = BitmapFactory.decodeResource(this.getResources(), R.drawable.moving_background_image);
scaledBitmap = bitmapImage.createScaledBitmap(bitmapImage, (int) movingImageWidth, (int) movingImageHeight, false);
movingBackgroundImageView.setImageBitmap(scaledBitmap);
backgroundImageInBeginning = true;
movingBackgroundImageView.post(new Runnable() {
@Override
public void run() {
movingBackgroundImageView.setImageMatrix(matrix);
moveBackground();
}
});
}
12-22 13: 44: 49,549 30885-30885/? E/AndroidRuntime: FATAL EXCEPTION: main Процесс: id.testingapp.android.TestingApp, PID: 30885 java.lang.OutOfMemoryError: не удалось выделить выделение байтов 26211852 с 14018312 бесплатными байтами и 13 МБ до тех пор, пока OOM в dalvik.system.VMRuntime.newNonMovableArray(собственный метод) at android.graphics.Bitmap.nativeCreate(собственный метод) at android.graphics.Bitmap.createBitmap(Bitmap.java:939) at android.graphics.Bitmap.createBitmap(Bitmap.java:912) at android.graphics.Bitmap.createBitmap(Bitmap.java:843) at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:719) на id.testingapp.android.TestingApp.WelcomeActivity.prepareBackgroundAnimation(WelcomeActivity.java:140) на id.TestingApp.android.TestingApp.WelcomeActivity.onCreate(WelcomeActivity.java:72) at android.app.Activity.performCreate(Activity.java:6283) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758) at android.app.ActivityThread.access $900 (ActivityThread.java:177) at android.app.ActivityThread $H.handleMessage(ActivityThread.java:1448) на android.os.Handler.dispatchMessage(Handler.java:102) на android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:5942) в java.lang.reflect.Method.invoke(собственный метод) в java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit $MethodAndArgsCaller.run(ZygoteInit.java:1400) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
EDIT:
Я попытался поместить все это в onDestroyed()
, но проблема сохраняется
@Override
protected void onDestroy() {
finish();
bitmapImage = null;
scaledBitmap = null;
super.onDestroy();
Runtime.getRuntime().gc();
System.gc();
}
Ответы
Ответ 1
Добавьте следующий код для него
@Override
protected void onDestroy() {
//android.os.Process.killProcess(android.os.Process.myPid());
super.onDestroy();
if(scaledBitmap!=null)
{
scaledBitmap.recycle();
scaledBitmap=null;
}
}
Ответ 2
В действии, если вы вызываете метод finish()
из уничтоженного и , все его ресурсы поставлены в очередь для сбора мусора.
Итак, вся память, которая была использована этой деятельностью, будет освобождена во время следующего цикла GC.
ИЛИ
вы можете попробовать это для очистки памяти,
@Override
public void onDestroy() {
super.onDestroy();
Runtime.getRuntime().gc();
}
проверьте этот, который поможет.
Ответ 3
даже после уничтожения активности, вызвав функцию finish(), ресурсы помещаются в очередь для сбора мусора. активность будет освобождена в течение следующего цикла GC.
@Override
public void onDestroy() {
super.onDestroy();
Runtime.getRuntime().gc();
}
Вы также можете использовать android:largeHeap="true"
для запроса большего размера кучи в теге приложения в манифесте.
Ответ 4
Попробуйте установить растровое изображение в значение null, пока действие будет уничтожено, и если желание запускает сборщик мусора.
Ответ 5
добавьте это в свой код
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
finish();
}
return super.onKeyDown(keyCode, event);
}
Ответ 6
попробуйте завершить операцию при нажатии кнопки
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
Ответ 7
Завершение операции не очищает память. Он удаляет только Activity из своего стека, Android очистит его память, когда ему понадобится память (сборка мусора), если вы столкнетесь с проблемой памяти с помощью drawable,
- Уменьшение размера чертежа может решить вашу проблему.
- Недостаточно памяти на устройствах Android также приводит к проблемам с памятью.