I am getting an OutOfMemoryError crash on only certain higher-end phones when displaying images. The worst ones seem to be the Samsung galaxy S4 and S5. I get no errors whatsoever on older phones or tablets, including the Nexus 4, and Samsung Galaxy Tab 2 10". The Nexus 5 seems to have no crashes either.
My app is a game book that displays long strings of text in a scrollview, and occasionally an image at the top of the scrollview. I have a background that is 450x750px in the background at all times. The images that I use in the imageviews from time to time are 700x900px. I also occasionally go to a battle with many images as well and then back to the scrollview with text and background.
Drastically reducing the sizes of my images in the drawable folder keeps the game from crashing immediately, but after several minutes of play, it still crashes when loading images and gives outofmemoryerror, especially on the Samsung Galaxy S5. On top of that, my drawable assets now look poor, as their size has been severely reduced to accommodate these newer devices, when high res images worked fine on older devices.
Most of my images are loaded in the XML, not programmatically in Java, either as backgrounds on views/layouts or as src's on imageviews. Since no tutorials seem to ever mention removing such image references from memory, I had thought it was safe to assume that they were collected and removed automatically. If that is not the case, I am unsure how to remove them and make more room in memory for new images.
Question: Is there any way to remove images from memory that are defined in XML once they have been displayed without nullifying the src, and thus making it not display the next time you want to view that layout?
I have considered no longer using android:background or android:src in the XML and just doing it programmatically instead, but I don't see why this should be necessary. To quote another StackOverflow user who asked a similar question and never had it properly answered: "Surely though, there must be a way of removing ImageViews from memory that are no longer used?"
If I need to do this all in java to avoid the memory errors, is this the proper form to remove the image from memory when I am done with it?
ImageView image = (ImageView) findViewById(R.id.illustration1);
image.setImageDrawable(null);
And then set it with this when I need it again?:
image.setImageResource(R.drawable.example_drawable);
The latest error report I received from a friend with a 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)
No comments:
Post a Comment