CartoDB / mobile-sdk

CARTO Mobile SDK core project
https://carto.com/docs/carto-engine/mobile-sdk/
BSD 3-Clause "New" or "Revised" License
185 stars 67 forks source link

ANR on Android 11 #387

Open mamykin-andrey opened 3 years ago

mamykin-andrey commented 3 years ago

Hello, we've faced with a strange ANR on Android 11. It will happen, if you use FragmentTransaction with AnimatorSet, which includes translate(X/Y) animation to a fragment, containing MapView.

Minimal reproducible example here - https://github.com/mamykin-av/CartoAnrSample, and video demonstration is here - https://www.youtube.com/watch?v=L4BOeiNV104.

Steps to reproduce:

  1. Open application
  2. Switch to map fragment by clicking on button
  3. Open Android home screen
  4. Return to the application
  5. ... ANR

I'm able to reproduce this bug on Emulator and on Pixel 4a (both with Android 11). I'm not sure about reason of this problem, but looks like native library blocks main thread. In logcat there aren't any heplful messages, and in data/anr I see this:

"main" prio=5 tid=1 Native

mtehver commented 3 years ago

Thanks for reporting this. There is both good and bad news about this.

The good news is that I managed to reproduce this using Pixel 2 and Emulator.

The bad news is that this really seems to be Android 11 bug related to interaction between fragments and GLSurfaceView (which is the base class of MapView). It is probably triggered when fragment manager is used with custom animations. Without 'translateX' animation it seems to work fine. I forked and modified the sample to remove CartoMobileSDK dependency and could still reproduce it: https://github.com/mtehver/CartoAnrSample.

I suggest reporting the issue to Google directly.

silentLOL commented 3 years ago

Hi. We experience the exact same thing with Android 11 and the LibGdx. Would be very interresting to know if you could overcome the problem.

farfromrefug commented 3 years ago

@mtehver i have a working example of Carto with TextureView if you are interested. I could create a PR. What we are seeing is a know issue (except the crashing) of GLSurfaceView. To have able to use fragment transitions you need to use a texture view.

RobartGmbH commented 3 years ago

My problems were solved by turning off the hardwareAcceleration in the Manifext.xml. See: https://stackoverflow.com/questions/14531868/android-opengl-issue-weird The root-cause could be that "openGL functionality is ran on the UIThread".

mtehver commented 3 years ago

@RobartGmbH Strange that turning off hardware acceleration fixes the issue. I looked into the Android source code of GLSurfaceView and it is quite a mess, using singleton mutexes. I tried various suggested workarounds, but they were very fragile. A workaround that seems to work is to override you fragment onPause and onResume methods as follows (the idea is to remove MapView in onPause and add it again in onResume):

class MapFragment : Fragment(R.layout.fragment_map) {
    var mGLSurfaceView: MapView? = null

    public override fun onPause() {
        super.onPause()
        if (mGLSurfaceView == null) {
            mGLSurfaceView = getView()?.findViewById<MapView>(R.id.map_view)
            (getView() as? ViewGroup)?.removeView(mGLSurfaceView)
        }
    }

    public override fun onResume() {
        if (mGLSurfaceView != null) {
            (getView() as? ViewGroup)?.addView(mGLSurfaceView)
            mGLSurfaceView = null;
        }
        super.onResume()
    }
}
mtehver commented 3 years ago

A small update - 4.4.0RC1 now includes TextureMapView class (contributed by @farfromrefug) that should fix the original issue without requiring workarounds.