在显示图像时,我只在某些高端手机上出现OutOfMemoryError崩溃。最糟糕的似乎是三星Galaxy S4和S5。我在旧手机或平板电脑上没有任何错误,包括Nexus 4和三星Galaxy Tab 2 10“.Nexus 5似乎也没有崩溃。
我的应用是一款游戏书,可在滚动视图中显示长串文本,偶尔会在滚动视图顶部显示图像。我的背景始终是450x750px的背景。我在图像视图中不时使用的图像是700x900像素。我偶尔也会和许多图像一起参加战斗,然后回到带有文字和背景的滚动视图。
大幅缩小可绘制文件夹中图像的大小可以防止游戏立即崩溃,但是在播放几分钟后,它仍然会在加载图像时出现崩溃并导致出现错误,特别是在三星Galaxy S5上。最重要的是,我的可绘制资产现在看起来很糟糕,因为当高分辨率图像在旧设备上正常工作时,它们的大小已经严重缩小以适应这些较新的设备。
我的大多数图像都是以XML格式加载的,而不是以Java编程方式加载,无论是作为视图/布局的背景还是作为图像视图上的src。由于没有任何教程似乎提到从内存中删除这些图像引用,我原以为可以安全地假设它们被自动收集和删除。如果情况并非如此,我不确定如何删除它们并为新图像留出更多空间。
问题:有没有办法从内存中删除XML中定义的图像,一旦显示它们而没有使src无效,从而使它在下次要查看时不显示布局?
我已经考虑过不再在XML中使用android:background或android:src而只是以编程方式执行它,但我不明白为什么这应该是必要的。引用另一个提出类似问题且从未正确回答的StackOverflow用户:“当然,必须有一种方法可以从不再使用的内存中删除ImageViews吗?”
如果我需要在java中完成所有操作以避免内存错误,那么当我完成它时,这是从内存中删除图像的正确形式吗?
ImageView image = (ImageView) findViewById(R.id.illustration1);
image.setImageDrawable(null);
然后再次需要时将其设置为?:
image.setImageResource(R.drawable.example_drawable);
我从朋友那里收到的有关Galaxy S5的最新错误报告:
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:701)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:526)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:889)
at android.content.res.Resources.loadDrawable(Resources.java:3453)
at android.content.res.Resources.getDrawable(Resources.java:1893)
at android.widget.ImageView.resolveUri(ImageView.java:648)
at android.widget.ImageView.setImageResource(ImageView.java:377)
at com.mywebsite.gamename.MainActivity.loadPage(MainActivity.java:1319)
at com.mywebsite.gamename.MainActivity$33.onClick(MainActivity.java:1997)
at android.view.View.performClick(View.java:4710)
at android.view.View$PerformClick.run(View.java:19510)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5678)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)