Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Jetpack compose Image in KMP project facing DiskReadViolation on StrictMode policy #3828

Closed
yuvaraj119 opened this issue Oct 16, 2023 · 3 comments · Fixed by #4965
Closed

Comments

@yuvaraj119
Copy link

Describe the problem
Explain the performance issue you're experiencing, including the following details:
When I'm loading image into Image component through painter from common main resource folder.
In android i enabled Strictmode policy at that point getting DiskReadViolation error.

  • What specific issue did you encounter? (e.g. missing frames, high CPU usage, memory leaks)
    Thread issue, Taking read operation longer than expected by Android system.
  • Have you noticed any patterns or specific circumstances under which the problem occurs?
    No

Affected platforms
Select one of the platforms below:

  • Android

If the problem is Android-only, report it in the Jetpack Compose tracker

Versions

  • Kotlin version: 1.8.10
  • Compose Multiplatform version: 1.5.0
  • OS version(s) (required for Desktop and iOS issues):
  • OS architecture (x86 or arm64):
  • JDK (for desktop issues): JDK 17

Error:
StrictMode policy violation; ~duration=855 ms: android.os.strictmode.DiskReadViolation at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1504) at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:241) at java.io.File.isDirectory(File.java:845) at dalvik.system.DexPathList$Element.maybeInit(DexPathList.java:696) at dalvik.system.DexPathList$Element.findResource(DexPathList.java:729) at dalvik.system.DexPathList.findResource(DexPathList.java:508) at dalvik.system.BaseDexClassLoader.findResource(BaseDexClassLoader.java:169) at java.lang.ClassLoader.getResource(ClassLoader.java:793) at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:987) at org.jetbrains.compose.resources.AndroidResourceImpl.readBytes(Resource.android.kt:17) at org.jetbrains.compose.resources.Resource_commonbutjsKt$readBytesSync$1.invokeSuspend(Resource.commonbutjs.kt:13) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:280) at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59) at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38) at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1) at org.jetbrains.compose.resources.Resource_commonbutjsKt.readBytesSync(Resource.commonbutjs.kt:13) at org.jetbrains.compose.resources.ComposeResource_commonKt.rememberImageBitmapSync(ComposeResource.common.kt:82) at org.jetbrains.compose.resources.ComposeResource_commonKt.access$rememberImageBitmapSync(ComposeResource.common.kt:1) at org.jetbrains.compose.resources.ComposeResource_commonKt$painterResource$1.invoke(ComposeResource.common.kt:120) at org.jetbrains.compose.resources.ComposeResource_commonKt$painterResource$1.invoke(ComposeResource.common.kt:120) at org.jetbrains.compose.resources.ComposeResource_commonKt.painterResource(ComposeResource.common.kt:102) at org.jetbrains.compose.resources.ComposeResource_commonKt.painterResource(ComposeResource.common.kt:120) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35) at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:132) at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:114) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228) at androidx.compose.material3.SurfaceKt.Surface-T9BRK9s(Surface.kt:111) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35) at androidx.compose.ui.layout.LayoutKt.MultiMeasureLayout(Layout.kt:443)

@yess-wee
Copy link

This issue is caused by a "DiskReadViolation" due to synchronous disk reads on the main thread, which can lead to UI unresponsiveness.To resolve this, you should perform disk operations asynchronously. Here's a suggested approach:

1)Move Disk Operations Off the Main Thread:

  • Use coroutines or background threads to handle disk I/O operations.
  1. Use Asynchronous APIs:
  • Look for asynchronous versions of the APIs being used for disk reads.

@terrakok
Copy link
Collaborator

This is fine. Resource files are being read on the MainThread (there is no difference for standard and compose resources).
The reason of the error is the android AssetManager is semi native implemented class. And, I guess, it is excluded from the StrictMode policy. You may ignore it but follow a rule: resources should be small enough. If you need to read big files then put them to the files directory and read them asynchronously.

@terrakok
Copy link
Collaborator

After #4965 the issue was fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants