1

I am encountering a recurring issue while working with the "Image" component in Android Compose. I am using the painterResource function to load images into the "Image" component. However, I'm facing frequent crashes related to java.lang.OutOfMemoryError.

I suspect that the crashes are occurring due to memory consumption associated with image loading. I would like to know the best practices and techniques to avoid these OutOfMemoryError crashes while using the "Image" component in Android Compose. Any insights into memory-efficient image loading strategies or other relevant optimizations would be greatly appreciated.

Thank you for your assistance in advance!

This is 1 of the crashes:

Fatal Exception: java.lang.OutOfMemoryError Failed to allocate a 18195852 byte allocation with 10423024 free bytes and 9MB until OOM dalvik.system.VMRuntime.newNonMovableArray (VMRuntime.java) android.graphics.BitmapFactory.nativeDecodeAsset (BitmapFactory.java) android.graphics.BitmapFactory.decodeStream (BitmapFactory.java:624) android.graphics.BitmapFactory.decodeResourceStream (BitmapFactory.java:457) android.graphics.drawable.Drawable.createFromResourceStream (Drawable.java:1152) android.content.res.ResourcesImpl.createFromResourceStream (ResourcesImpl.java:1296) android.content.res.ResourcesImpl.loadDrawableForCookie (ResourcesImpl.java:743) android.content.res.ResourcesImpl.loadDrawable (ResourcesImpl.java:585) android.content.res.MiuiResourcesImpl.loadDrawable (MiuiResourcesImpl.java:328) android.content.res.Resources.getDrawable (Resources.java:785) androidx.compose.ui.res.ImageResources_androidKt.imageResource (ImageResources.android.kt:39) androidx.compose.ui.res.PainterResources_androidKt.loadImageBitmapResource (PainterResources.android.kt:109) androidx.compose.ui.res.PainterResources_androidKt.access$loadImageBitmapResource (PainterResources.android.kt:1) androidx.compose.ui.res.PainterResources_androidKt.painterResource (PainterResources.android.kt:70) com.ui.screens.main.MainScreenKt$VipLevels$$inlined$ConstraintLayout$5.invoke (ConstraintLayout.kt:2308) androidx.constraintlayout.compose.ConstraintLayoutKt$ConstraintLayout$2.invoke (ConstraintLayout.kt:470) com.ui.screens.main.MainScreenKt$VipLevels$$inlined$ConstraintLayout$5.invoke (ConstraintLayout.kt:470) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:108) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:35) androidx.compose.runtime.ComposablesKt.ReusableComposeNode (Composables.kt:373) androidx.compose.ui.layout.LayoutKt.MultiMeasureLayout (Layout.kt:251) androidx.constraintlayout.compose.ConstraintLayoutKt.ConstraintLayout (ConstraintLayout.kt:467) com.ui.screens.main.MainScreenKt.VipLevels (MainScreen.kt:314) com.ui.screens.main.MainScreenKt$MainScreen$$inlined$ConstraintLayout$5.invoke (ConstraintLayout.kt:2394) androidx.constraintlayout.compose.ConstraintLayoutKt$ConstraintLayout$2.invoke (ConstraintLayout.kt:470) com.ui.screens.main.MainScreenKt$MainScreen$$inlined$ConstraintLayout$5.invoke (ConstraintLayout.kt:470) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:108) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:35) androidx.compose.runtime.ComposablesKt.ReusableComposeNode (Composables.kt:373) androidx.compose.ui.layout.LayoutKt.MultiMeasureLayout (Layout.kt:251) androidx.constraintlayout.compose.ConstraintLayoutKt.ConstraintLayout (ConstraintLayout.kt:467) com.ui.screens.main.MainScreenKt.MainScreen (MainScreen.kt:127) com.ui.screens.main.MainScreenRoute.Content (MainScreen.kt:69) com.navigation.NavRoute$composable$1.invoke (NavRoute.kt:100) com.navigation.NavRoute$composable$1.access$invoke$lambda$0 (NavRoute.kt:59) com.navigation.NavRoute$composable$1.invoke (NavRoute.kt:59) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:117) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:35) androidx.navigation.compose.NavHostKt$NavHost$4$2.invoke (NavHost.kt:173) androidx.navigation.compose.NavHostKt$NavHost$4$2.invoke (NavHost.kt:172) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:108) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:35) androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider (CompositionLocal.kt:248) androidx.compose.runtime.saveable.SaveableStateHolderImpl.SaveableStateProvider (SaveableStateHolder.kt:84) androidx.navigation.compose.NavBackStackEntryProviderKt.SaveableStateProvider (NavBackStackEntryProvider.kt:65) androidx.navigation.compose.NavBackStackEntryProviderKt.access$SaveableStateProvider (NavBackStackEntryProvider.kt:1) androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke (NavBackStackEntryProvider.kt:52) androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke (NavBackStackEntryProvider.kt:51) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:108) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:35) androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider (CompositionLocal.kt:228) androidx.navigation.compose.NavBackStackEntryProviderKt.LocalOwnersProvider (NavBackStackEntryProvider.kt:47) androidx.navigation.compose.NavHostKt$NavHost$4.invoke (NavHost.kt:172) androidx.navigation.compose.NavHostKt$NavHost$4.invoke (NavHost.kt:146) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:117) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:35) androidx.compose.animation.CrossfadeKt$Crossfade$5$1.invoke (Crossfade.kt:133) androidx.compose.animation.CrossfadeKt$Crossfade$5$1.access$invoke$lambda$1 (Crossfade.kt:128) androidx.compose.animation.CrossfadeKt$Crossfade$5$1.invoke (Crossfade.kt:128) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:108) androidx.compose.runtime.internal.ComposableLambdaImpl.invoke (ComposableLambda.jvm.kt:35) androidx.compose.animation.CrossfadeKt.Crossfade (Crossfade.kt:142) androidx.compose.animation.CrossfadeKt.Crossfade (Crossfade.kt:73) androidx.navigation.compose.NavHostKt.NavHost (NavHost.kt:146) androidx.navigation.compose.NavHostKt$NavHost$5.invoke (NavHost.kt:2) androidx.navigation.compose.NavHostKt$NavHost$5.invoke (NavHost.kt:1) androidx.compose.runtime.RecomposeScopeImpl.compose (RecomposeScopeImpl.kt:192) androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd (Composer.kt:2511) androidx.compose.runtime.ComposerImpl.skipCurrentGroup (Composer.kt:2780) androidx.compose.runtime.ComposerImpl.doCompose (Composer.kt:3259) androidx.compose.runtime.ComposerImpl.recompose$runtime_release (Composer.kt:3210) androidx.compose.runtime.CompositionImpl.recompose (Composition.kt:864) androidx.compose.runtime.Recomposer.performRecompose (Recomposer.kt:1125) androidx.compose.runtime.Recomposer.access$setCloseCause$p (Recomposer.kt:124) androidx.compose.runtime.Recomposer.access$performRecompose (Recomposer.kt:124) androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke (Recomposer.kt:580) androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke (Recomposer.kt:548) androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame (AndroidUiFrameClock.android.kt:41) androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch (AndroidUiDispatcher.android.kt:109) androidx.compose.ui.platform.AndroidUiDispatcher.access$setScheduledFrameDispatch$p (AndroidUiDispatcher.android.kt:41) androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch (AndroidUiDispatcher.android.kt:41) androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame (AndroidUiDispatcher.android.kt:69) android.view.Choreographer$CallbackRecord.run (Choreographer.java:871) android.view.Choreographer.doCallbacks (Choreographer.java:685) android.view.Choreographer.doFrame (Choreographer.java:618) android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:859) android.os.Handler.handleCallback (Handler.java:754) android.os.Handler.dispatchMessage (Handler.java:95) android.os.Looper.loop (Looper.java:165) android.app.ActivityThread.main (ActivityThread.java:6375) java.lang.reflect.Method.invoke (Method.java) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:912) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:802) 
2
  • Do you try to load multiple images per screen or is it only one image? The given exception says that the image is ~17MB. If you try to show multiple images of that size, then yes, it could lead to an OOMException. Try to downscale the image(s) before you show them: stackoverflow.com/questions/3331527/… Commented Sep 11, 2023 at 12:07
  • I solved the issue, checked my answer below @user1185087 Commented Sep 11, 2023 at 14:21

1 Answer 1

2

SOLVED

I use one size for all images. I moved all images from the "drawable" folder to the "drawable-nodpi" folder. It's possible that the system was attempting to scale the images to fit various screen sizes, and by doing this, the issue no longer occurs on some devices due to large image sizes.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.