I want to change the background image of my Activity's layout every time I launch that activity. For that reason, inside onResume(), I am randomly setting the background image of layout like this:

@Override
public void onResume(){
    super.onResume();
    Random r = new Random();
    int randNumber = r.nextInt(homeBackgroundImage.length);
    mBackgroundLayout.setBackground(ResourcesCompat.getDrawable(getResources(), homeBackgroundImage[randNumber], null));
}

But, I am getting exception in the following line:

mBackgroundLayout.setBackground(ResourcesCompat.getDrawable(getResources(), homeBackgroundImage[randNumber], null));

This is the logcat output:

java.lang.OutOfMemoryError: Failed to allocate a 756946956 byte allocation with 16777216 free bytes and 433MB until OOM
                                                                        at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
                                                                        at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
                                                                        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
                                                                        at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
                                                                        at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
                                                                        at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635)
                                                                        at android.content.res.Resources.loadDrawable(Resources.java:2540)
                                                                        at android.content.res.Resources.getDrawable(Resources.java:806)
                                                                        at android.support.v4.content.res.ResourcesCompatApi21.getDrawable(ResourcesCompatApi21.java:27)
                                                                        at android.support.v4.content.res.ResourcesCompat.getDrawable(ResourcesCompat.java:60)
                                                                        at in.avara.app.avaravrplayer.Activity.MainActivity.onResume(MainActivity.java:167)
                                                                        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
                                                                        at android.app.Activity.performResume(Activity.java:6327)
                                                                        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
                                                                        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
                                                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
                                                                        at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                        at android.os.Looper.loop(Looper.java:148)
                                                                        at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Someone, please suggest me What is the optimized and best way to change background image of a layout randomly on every launch.

NOTE: I have already tried adding android:hardwareAccelerated="false" , android:largeHeap="true". But, it didn't work in my case.

Thanks in advance!

2

There are 2 best solutions below

0
On

You are attempting to allocate 756946956 bytes ~= 721MB. This is much too large.

Moreover, 756946956 bytes represents the equivalent of a 13756 x 13756 pixel image. This is far larger than any Android screen.

You need to identify the image that is failing and reduce its resolution significantly.

If you put this image in res/drawable/, bear in mind that res/drawable/ is a synonym of res/drawable-mdpi/. Your image will be upsampled when you use that drawable on higher screen densities (e.g., xhdpi). You probably should move that drawable out of res/drawable/ and into either a density-specific directory for the desired density (e.g., res/drawable-xhdpi/), or into res/drawable-nodpi/ to disable this density-based resampling.

0
On

Try to put move your images from res/drawable/ to res/drawable/drawable-nodpi. If problem is still here, in your manifest under application put android:largeHeap="true".