J'ai un lanceur Activity
qui charge et redimensionne un gros bitmap en tant qu'arrière-plan à son ouverture.
Chaque fois que vous appuyez sur le bouton Précédent, la variable Activity
est destroyed
. Mais je pense que la mémoire n'est pas encore libérée.
Lorsque j'ouvre l'application en arrière, appuyez sur le bouton Précédent et ouvrez-la à nouveau (plusieurs fois), je vais obtenir une OutOfMemoryError
.
Je suis désolé pour cette question de débutant, mais je me demande comment puis-je libérer la mémoire chaque fois qu'une Activity
est 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: EXCEPTION FATALE: main Processus: id.testingapp.Android.TestingApp, PID: 30885 Java.lang.OutOfMemoryError: Impossible d'allouer une allocation de 26211852 octets avec 14018312 octets libres et 13 Mo jusqu'au MOO at dalvik.system.VMRuntime.newNonMovableArray (Native Method) sur Android.graphics.Bitmap.nativeCreate (Native Method) sur Android.graphics.Bitmap.createBitmap (Bitmap.Java:939) sur Android.graphics.Bitmap.createBitmap (Bitmap.Java:912) sur Android.graphics.Bitmap.createBitmap (Bitmap.Java:843) sur 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) sur Android.app.Activity.performCreate (Activity.Java:6283) sur Android.app.Instrumentation.callActivityOnCreate (Instrumentation.Java:1119) sur Android.app.ActivityThread.performLaunchActivity (ActivityThread.Java:2646) sur Android.app.ActivityThread.handleLaunchActivity (ActivityThread.Java:2758) sur Android.app.ActivityThread.access 900 $ (ActivityThread.Java:177) sur Android.app.ActivityThread $ H.handleMessage (ActivityThread.Java:1448) sur Android.os.Handler.dispatchMessage (Handler.Java:102) sur Android.os.Looper.loop (Looper.Java:145) sur Android.app.ActivityThread.main (ActivityThread.Java:5942) à Java.lang.reflect.Method.invoke (Méthode native) à Java.lang.reflect.Method.invoke (Method.Java:372) sur com.Android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.Java:1400) sur com.Android.internal.os.ZygoteInit.main (ZygoteInit.Java:1195)
MODIFIER:
J'ai essayé de mettre tout cela en onDestroyed()
mais le problème persiste
@Override
protected void onDestroy() {
finish();
bitmapImage = null;
scaledBitmap = null;
super.onDestroy();
Runtime.getRuntime().gc();
System.gc();
}
Ajoutez le code suivant pour cela
@Override
protected void onDestroy() {
//Android.os.Process.killProcess(Android.os.Process.myPid());
super.onDestroy();
if(scaledBitmap!=null)
{
scaledBitmap.recycle();
scaledBitmap=null;
}
}
En activité si vous appelez, la méthode finish()
est détruite et toutes ses ressources sont mises en file d'attente pour la récupération de place.
Ainsi, toute la mémoire utilisée par cette activité sera libérée lors du prochain cycle du GC.
OR
vous pouvez essayer ceci pour nettoyer la mémoire,
@Override
public void onDestroy() {
super.onDestroy();
Runtime.getRuntime().gc();
}
vérifier ces détails . J'espère que cela pourra aider.
ajoutez ceci à votre code
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
finish();
}
return super.onKeyDown(keyCode, event);
}
même après avoir détruit l'activité en appelant finish (), ses ressources sont mises en file d'attente pour la récupération de place. l'activité sera libérée au cours du prochain cycle du GC.
@Override
public void onDestroy() {
super.onDestroy();
Runtime.getRuntime().gc();
}
Vous pouvez également utiliser Android:largeHeap="true"
pour demander une taille de segment supérieure, dans votre balise d'application dans le manifeste.
Essayez de définir le bitmap sur null lorsque l'activité est détruite et, si vous le souhaitez, exécutez le ramasse-miettes.
essayez de terminer l'activité en appuyant sur le bouton de retour
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
Terminer une activité n'efface pas sa mémoire. Il ne supprime que l'activité de sa pile, Android effacera sa mémoire lorsqu'il en aura besoin