Android - 释放分配的内存AnimationDrawable正在用完

Raj*_*ana 9 java android memory-leaks memory-management animationdrawable

我有一个复杂的Battle系统,它有1个父Activity,然后是几个子类,通过扩展Battle并将上下文传递给这些类来访问BattleActivity的静态变量.

这一切似乎都运行正常,但是我在从内存中释放所有的AnimationDrawables时遇到了问题.在整个战斗中总共可以使用24个DrawableAnimations.现在这是可以的,但是每次用户遇到一个新的怪物时,就会有4个以上的AnimationDrawables被添加到内存中,这将慢慢地使得我的应用程序崩溃,并且内存不足异常.

因此,我真的需要找到一种方法来释放我的战斗系统在我退出时占用的所有内存.目前,我正在测试Sony Z2,当用户参加战斗时,记忆从91mb增加到230mb.当战斗迫使我需要将这个内存使用量降低到91mb.我添加了一些非常基本的代码片段,让您了解应用程序当前的流程以及我尝试释放内存的方法.

public class Battle extends Activity
{
     // I have several AnimationDrawables loaded into memory
     // These are then assigned the relevent animation to a button swicthing between these animations throughout my battle
    ImageButton btnChr1;
    AnimationDrawable cAnimHit1;
}

//This is the use of one of those AnimationDrawables
public class Battle_Chr_Anim extends Battle
{
    protected Context ctx;
    private ImageButton btnChr1;
    AnimationDrawable cAnimHit1;

    public Battle_Chr_Anim(Context c, ImageButton _btnChr1, AnimationDrawable _cAnimHit1) { 
        this.ctx = c;
        this.btnChr1 = _btnChr1;
        this.cAnimHit1 = _cAnimHit1;
    }

    // Bound the ImageButton
    int id = ctx.getResources().getIdentifier("idle", "drawable", ctx.getPackageName());
    img_chr1.setBackgroundResource(id);
    frameAnimation = (AnimationDrawable)img_chr1.getBackground();
    frameAnimation.start()

    // Loaded into memory ready so I can swicth them over quickly when user attacks
    int ca1 = ctx.getResources().getIdentifier("attack", "drawable", ctx.getPackageName());
    cAnimHit1 = (AnimationDrawable)chrHit1.getBackground();
    cAnimHit1.start();
}

public class Battle_Ended extends Battle
{
    protected Context ctx;

    public Battle_Ended(Context c) { 
        this.ctx = c;
    }

    //This is a dialog popup when the user completes the battle closing the battle activty
    void EndBattle()
    {
        ImageButton btnSubmit = (ImageButton)dialog.findViewById(R.id.imgBtnSubmit);
        btnSubmit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent returnIntent = new Intent();
                setResult(RESULT_CANCELED, returnIntent);
                RecyleAllAnimations();
                dialog.dismiss();
                ((Activity) ctx).finish();
            }
        });
    }

    void RecyleAllAnimations()
    {
        // I want all AnimationDrawables from memory here, I believe the below line removes the one currently in use, however I have no way of releasing the other animations sitting in memory.
        img_chr1.setBackgroundResource(android.R.color.transparent);
        System.gc();
    }
}
Run Code Online (Sandbox Code Playgroud)

mml*_*loo 0

首先,我认为AnimationDrawable除非您离开它们声明的范围,否则您不能进行任何回收。不要继续System.gc();,让 GC 自动为您释放这些内存。

访问 BattleActivity 的静态变量

这是你的第一个错误。如果你使用静态变量,即使你离开你的活动,它们都在那里,你肯定会遇到 OOM。

因此,我真的需要找到一种方法,在我退出时立即释放我的战斗系统占用的所有内存。

如果将所有变量声明为非静态变量,那么当您离开它们定义的范围时,您将不会遇到 OOM。尽管如果您AnimationDrawable在活动运行期间没有任何限制地创建,您可能会遇到 OOM。