mapbox / mapbox-maps-android

Interactive, thoroughly customizable maps in native Android powered by vector tiles and OpenGL.
https://www.mapbox.com/mobile-maps-sdk
Other
466 stars 131 forks source link

StrictMode turned on complains about Choreographer.dispose not called #942

Open yunikkk opened 2 years ago

yunikkk commented 2 years ago

Issue moved from #863, cc @alexzatsepin

This issue can be easily reproduced if the following StrictPolicy enabled:

StrictMode.setVmPolicy(
  StrictMode.VmPolicy.Builder()
    .detectLeakedClosableObjects()
    .penaltyLog()
    .penaltyDeath()
    .build()
)

Steps to reproduce:

  1. Launch the app to view the map
  2. Close the app by "Back" pressed
  3. Launch the app again

Actual result:

2021-12-02 14:27:34.951 25024-25042/com.mapbox.dash.debug D/StrictMode: StrictMode policy violation: android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
        at android.os.StrictMode$AndroidCloseGuardReporter.report(StrictMode.java:1924)
        at dalvik.system.CloseGuard.warnIfOpen(CloseGuard.java:303)
        at android.view.DisplayEventReceiver.dispose(DisplayEventReceiver.java:136)
        at android.view.DisplayEventReceiver.finalize(DisplayEventReceiver.java:120)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:292)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:279)
        at java.lang.Daemons$Daemon.run(Daemons.java:140)
        at java.lang.Thread.run(Thread.java:923)
     Caused by: java.lang.Throwable: Explicit termination method 'dispose' not called
        at dalvik.system.CloseGuard.openWithCallSite(CloseGuard.java:259)
        at dalvik.system.CloseGuard.open(CloseGuard.java:230)
        at android.view.DisplayEventReceiver.<init>(DisplayEventReceiver.java:114)
        at android.view.Choreographer$FrameDisplayEventReceiver.<init>(Choreographer.java:1004)
        at android.view.Choreographer.<init>(Choreographer.java:273)
        at android.view.Choreographer.<init>(Choreographer.java:83)
        at android.view.Choreographer$1.initialValue(Choreographer.java:115)
        at android.view.Choreographer$1.initialValue(Choreographer.java:108)
        at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180)
        at java.lang.ThreadLocal.get(ThreadLocal.java:170)
        at android.view.Choreographer.getInstance(Choreographer.java:302)
        at com.mapbox.maps.renderer.MapboxRenderThread.prepareRenderFrame(MapboxRenderThread.kt:249)
        at com.mapbox.maps.renderer.MapboxRenderThread.access$prepareRenderFrame(MapboxRenderThread.kt:26)
        at com.mapbox.maps.renderer.MapboxRenderThread$onSurfaceCreated$$inlined$withLock$lambda$1.invoke(MapboxRenderThread.kt:304)
        at com.mapbox.maps.renderer.MapboxRenderThread$onSurfaceCreated$$inlined$withLock$lambda$1.invoke(MapboxRenderThread.kt:26)
        at com.mapbox.maps.renderer.RenderHandlerThread$post$$inlined$let$lambda$1.run(RenderHandlerThread.kt:21)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:236)
        at android.os.HandlerThread.run(HandlerThread.java:67)
2021-12-02 14:27:34.951 25024-25042/com.mapbox.dash.debug W/System.err: StrictMode VmPolicy violation with POLICY_DEATH; shutting down.

Environment: Samsung galaxy TAB S5e, Android 11 Xiaomi MI 10 Lite, Android 11

yunikkk commented 2 years ago

It seems that problem is not really related to our code. Choreographer instance has thread local instance that could be actually disposed but method is hidden, https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/Choreographer.java#318. It was added at https://android.googlesource.com/platform/frameworks/base/+/ac04f4e69a6de138c5afc668a2c89b7da7ff4e6a for the internal usage within the SDK to release file descriptors faster and not rely on GC.

There are examples of reflection that make use of this method https://github.com/bilibili/DanmakuFlameMaster/issues/376, we could potentially do the same thing if for some reason decide it's good optimization.

samirasalah commented 1 year ago

@yunikkk

Hi, any update for this issue pls?

yunikkk commented 1 year ago

@samirasalah no updates so far. The hack calling Choreographer.releaseInstance using reflection won't work on modern devices since it's blacklisted in the 8+ Androids, e.g. https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces from the csv : Landroid/view/Choreographer;->releaseInstance()V,lo-prio,max-target-o. I'm afraid the only thing to do is to disable / configure StrictMode to ignore this specific issue.

samirasalah commented 1 year ago

@yunikkk thank's for your reply. Have a nice day