在带有24MB堆的WVGA800屏幕的API_14模拟器中运行我的视图背景图像出现问题,看起来在视图导航之间没有释放可绘制的内容以及显示3个视图后出现内存不足异常膨胀视图。
应用程序以SplashScreenActivity开头,其中有一个480x800 PNG作为其背景图像,用于启动启动画面。该应用程序继续导航到其下一个视图,该视图也显示新的480x800像素。第三个屏幕导航还包含480x800 PNG,当出现内存不足错误时。首先,我尝试在axml布局中设置背景。然后我尝试了从SplashScreenActivity.OnCreate()中的代码设置背景的替代方法和另外两个视图OnCreate()方法。我在其他地方读过,如果这是问题,那么从单声道vm处理它的可绘制释放。另一个有用的技巧是在OnCreate()的开头强制使用GC,这使得12%的堆空闲,但这只取得了有限的成功。
public class SplashScreenActivity: MvxBaseSplashScreenActivity
{
public SplashScreenActivity() : base(Resource.Layout.SplashScreen) { }
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
using (var drawable = Resources.GetDrawable(Resource.Drawable.LoadingScreen))
Window.SetBackgroundDrawable(drawable);
}
}
第二个观点
public class GameView : MvxBindingActivityView<GameViewModel>
{
public GameView() { SoundBinding.GameView = this; }
protected override void OnViewModelSet() { SetContentView(Resource.Layout.GameView); }
protected override void OnCreate(Bundle bundle)
{
GC.Collect();
base.OnCreate(bundle);
using (var drawable = Resources.GetDrawable(Resource.Drawable.GameScreenBackground))
Window.SetBackgroundDrawable(drawable);
}
}
毕竟这个应用程序仍然耗尽了内存,在第三个类似的背景视图中膨胀。有时它会工作,然后随着屏幕循环最终它发生。我查看MAT上的堆转储,我可以看到两个大小为3.5M的bitmapDrawables。我认为这些是我的两个位图。对于第二个BitmapDrawable,我可以清楚地看到保持它的视图。内存中还有另一个位图,但我无法看到它的GC根路径是什么。这必须是第一个SplashScreenActivity视图中第一个加载的PNG。这是它的GC路径到GC根没有弱refs。弱者也持有它。
android.graphics.Bitmap @ 0x4134fb08 | 40 | 3,456,056
|- mBitmap android.graphics.drawable.BitmapDrawable @ 0x4134f568 | 64 | 136
| |- mBackgroundDrawable com.android.internal.policy.impl.PhoneWindow @ 0x41356cc8 Native Stack | 200 | 1,168
| |- mBGDrawable com.android.internal.policy.impl.PhoneWindow$DecorView @ 0x41357560 Native Stack| 560 | 968
| '- Total: 2 entries | |
|- mBitmap android.graphics.drawable.BitmapDrawable$BitmapState @ 0x4134f460 | 40 | 40
| '- referent java.lang.ref.WeakReference @ 0x4134ff40 | 24 | 24
'- Total: 2 entries | |
所以提问时间。如何确保在下一个视图膨胀之前释放这些drawable?是否有必要在代码中设置背景而不是视图的布局?我是否需要通过将回调设置为null来解除绑定()Drawable vs Single reusable Bitmap better with memory?? 我调查了视图的OnDestroy(),但我发现在创建新视图之前没有调用它们。当从一个视图导航到另一个视图时,可以确保视图被破坏,这有助于在下一个视图膨胀之前释放我的资源。
有关如何更好地管理我的应用中的这些资源的任何建议将非常感激。
答案 0 :(得分:1)
是否有一个简单的示例应用程序可以在任何可以重现此行为的地方发布?你能在非Mvvm应用程序中重现同样的问题吗?在非MonoDroid Java应用程序中?
感觉您可能在Android或MonoDroid层看到泄漏。我相信Conference app使用Window.SetBackgroundDrawable
中的所有观点并没有在那里报告过问题。 (可能我的图像更小?)
作为一种解决方法,您可以尝试的一件事是覆盖Activity Lifecycle中的OnPause和OnResume方法,以便清除和重置可绘制的背景。
然而,这只是一种解决方法......我认为在这里完成解决方案是值得的。