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

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

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

因此,我真的需要find一种方法来释放我的战斗系统在我退出时占用的所有内存。 目前,我正在测试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(); } } 

首先,我认为你不能为AnimationDrawable做任何回收,除非你离开声明它们的范围。 不要在System.gc();上转发System.gc(); 并让GC自动为您释放这些内存。

它访问BattleActivity的静态variables

这是你的第一个错误。 如果你使用静态variables即使你离开你的活动他们都在那里你肯定会得到OOM。

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

如果您将所有variables声明为非静态variables,那么当您离开定义的范围时,您将不会获得OOM。 虽然如果在活动运行期间创建没有任何边界的AnimationDrawable您可能会获得OOM。

使用静态Drawable(s)或View(s)将导致内存泄漏,因为drawables是有状态的。

您可以检查任何其他静态Drawable(s)或View(s)并删除它们或调用

 drawable.setCallback(null); 

你不能回收Drawable对象,调用System.gc()不是一个好习惯。

看来您的应用程序在某处遇到了内存泄漏,如果您尝试了上述操作并且内存仍以该速率扩展,那么请考虑进行内存分析以缩小问题范围。