web-dev-qa-db-fra.com

Libère la mémoire d'une activité particulière lorsqu'elle est détruite

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();
}
19
JayVDiyk

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;
            }

     }
11
Ravindra Kushwaha

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.

7
Amit Vaghela

ajoutez ceci à votre code

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    if ((keyCode == KeyEvent.KEYCODE_BACK))
    {
        finish();
    }
    return super.onKeyDown(keyCode, event);
}
2
Jatin Khattar

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.

2
Androider

Essayez de définir le bitmap sur null lorsque l'activité est détruite et, si vous le souhaitez, exécutez le ramasse-miettes.

2
ajantha

essayez de terminer l'activité en appuyant sur le bouton de retour

@Override
public void onBackPressed() {
    super.onBackPressed();
    finish();
}
1
Anbarasu Chinna

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 

  • Réduire la taille imprimable peut résoudre votre problème.
  • Une mémoire insuffisante sur les appareils Android entraîne également des problèmes de mémoire.
0
Anbarasu Chinna