Search Unity

ANR in com.unity3d.player.UnityPlayer.updateDisplayInternal

Discussion in 'Android' started by Le-Tuan-Son, Sep 22, 2021.

  1. Le-Tuan-Son

    Le-Tuan-Son

    Joined:
    Jan 13, 2016
    Posts:
    21
    Hi I get a lot of ANR related to com.unity3d.player.UnityPlayer.updateDisplayInternal.
    Unity 2019.4.25f1

    The common flow is :
    .....App Stoped/App Paused
    ...
    -> com.unity3d.player.UnityPlayer$21.surfaceDestroyed
    ...
    -> com.unity3d.player.UnityPlayer.updateDisplayInternal
    -> java.util.concurrent.Semaphore.tryAcquire

    Here is more detailed log(I use ANR watchdog to get it):

    Code (CSharp):
    1. sun.misc.Unsafe.park (Unsafe.java)
    2. java.util.concurrent.locks.LockSupport.parkNanos (LockSupport.java:230)
    3. java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos (AbstractQueuedSynchronizer.java:1063)
    4. java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos (AbstractQueuedSynchronizer.java:1358)
    5. java.util.concurrent.Semaphore.tryAcquire (Semaphore.java:415)
    6. com.unity3d.player.UnityPlayer.updateDisplayInternal (Unknown Source:54)
    7. com.unity3d.player.UnityPlayer.updateGLDisplay (Unknown Source:5)
    8. com.unity3d.player.UnityPlayer.access$1100
    9. com.unity3d.player.UnityPlayer$21.surfaceDestroyed (Unknown Source:4)
    10. android.view.SurfaceView.updateSurface (SurfaceView.java:879)
    11. android.view.SurfaceView.windowStopped (SurfaceView.java:315)
    12. android.view.ViewRootImpl.setWindowStopped (ViewRootImpl.java:1977)
    13. android.view.WindowManagerGlobal.setStoppedState (WindowManagerGlobal.java:709)
    14. android.app.Activity.performStop (Activity.java:8181)
    15. android.app.ActivityThread.callActivityOnStop (ActivityThread.java:4987)
    16. android.app.ActivityThread.handleSleeping (ActivityThread.java:5124)
    17. android.app.ActivityThread.access$2500 (ActivityThread.java:270)
    18. android.app.ActivityThread$H.handleMessage (ActivityThread.java:2149)
    19. android.os.Handler.dispatchMessage (Handler.java:107)
    20. android.os.Looper.loop (Looper.java:237)
    21. android.app.ActivityThread.main (ActivityThread.java:7948)
    22. java.lang.reflect.Method.invoke (Method.java)
    23. com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
    24. com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1075)
    And here is function UnityPlayer.updateDisplayInternal
    Code (CSharp):
    1. private boolean updateDisplayInternal(final int var1, final Surface var2) {
    2.         if (n.c() && this.mState.e()) {
    3.             final Semaphore var3 = new Semaphore(0);
    4.             Runnable var4 = new Runnable() {
    5.                 public final void run() {
    6.                     UnityPlayer.this.nativeRecreateGfxState(var1, var2);
    7.                     var3.release();
    8.                 }
    9.             };
    10.             if (var1 == 0) {
    11.                 if (var2 == null) {
    12.                     this.m_MainThread.b(var4);
    13.                 } else {
    14.                     this.m_MainThread.c(var4);
    15.                 }
    16.             } else {
    17.                 var4.run();
    18.             }
    19.  
    20.             if (var2 == null && var1 == 0) {
    21.                 try {
    22.                     if (!var3.tryAcquire(4L, TimeUnit.SECONDS)) {
    23.                         g.Log(5, "Timeout while trying detaching primary window.");
    24.                     }
    25.                 } catch (InterruptedException var5) {
    26.                     g.Log(5, "UI thread got interrupted while trying to detach the primary window from the Unity Engine.");
    27.                 }
    28.             }
    29.  
    30.             return true;
    31.         } else {
    32.             return false;
    33.         }
    34.     }
    Do anyone have similar problem or any idea to overcome it?
    Thank you.
     
  2. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,919
    I think someone reported it in the past, but since there's no exact steps on how to repro it, it wasn't fixed. One of the potential fixes for this is to set https://docs.unity3d.com/ScriptReference/Screen-sleepTimeout.html to SleepTimeout.NeverSleep.
     
  3. Le-Tuan-Son

    Le-Tuan-Son

    Joined:
    Jan 13, 2016
    Posts:
    21
    Thank you Tomas!! I'll try it.

    I can't reproduce on my end too. It's happened on wide range of devices, android versions.
    The only notable info is 76% of this ANR is when app in background.
     
    Last edited: Sep 22, 2021
  4. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,919
    Out of curiosity, how do you know that app is in background? Because of the stacktrace?
     
  5. Le-Tuan-Son

    Le-Tuan-Son

    Joined:
    Jan 13, 2016
    Posts:
    21
    Hi Tomas, Crashlytic has that info.
     

    Attached Files:

    VIetHoang1603 and Tomas1856 like this.
  6. chengdragon198

    chengdragon198

    Joined:
    Mar 2, 2016
    Posts:
    6
    Code (JavaScript):
    1.     public  void pause() {
    2.         Log.i(TAG, "pause: start--"+isShow);
    3.         if(true){
    4.             super.pause();
    5.             for (int i = 0; i < getChildCount(); i++) {
    6.                 final View child =getChildAt(i);
    7.                 if(null!=child){
    8.                     Log.i(TAG,"pause---"+child.toString());
    9.                     post(new Runnable() {
    10.                         @Override
    11.                         public void run() {
    12.                             child.setVisibility(View.GONE);
    13.                         }
    14.                     });
    15.  
    16.                 }
    17.  
    18.             }
    19.             windowFocusChanged(false);
    20.             isShow=false;
    21.         }
    22.         Log.i(TAG, "pause: end");
    23.     }

    Is there a solution to this problem?I modified the pasue () of unityplay and called pause (), which caused the same problem.
     
  7. Le-Tuan-Son

    Le-Tuan-Son

    Joined:
    Jan 13, 2016
    Posts:
    21
    Unfortunately, I didn't find any. Tried to remove all code in OnDisable, OnDestroy, OnApplicationPause, OnApplicationQuit. But the ANR still high.
     
  8. iMobilityTeam

    iMobilityTeam

    Joined:
    Nov 5, 2018
    Posts:
    5
    same issue
     
  9. arsalaan

    arsalaan

    Joined:
    Aug 27, 2020
    Posts:
    2
    Hi , any update on this ?
     
  10. AntonPetrov

    AntonPetrov

    Joined:
    Dec 27, 2013
    Posts:
    64
    @Tomas1856 The majority of our ANR start with `com.unity3d.player.UnityPlayer.surfaceDestroyed` too. My guess is UnityPlayer blocks 'main' thread waiting on some semaphore for something queued on to 'UnityMain' or other thread. I have no access to sources to check this hypothesis and I have no clues how to resolve that ANR.
    Can you help with investigation, please?
     
  11. iMobilityTeam

    iMobilityTeam

    Joined:
    Nov 5, 2018
    Posts:
    5
  12. iMobilityTeam

    iMobilityTeam

    Joined:
    Nov 5, 2018
    Posts:
    5
    Up top, i have same issue
     
  13. ageana

    ageana

    Joined:
    Nov 6, 2013
    Posts:
    48
    up


    Code (CSharp):
    1. main (timed waiting): tid=1 systid=16340
    2.        at sun.misc.Unsafe.park(Native method)
    3.        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:230)
    4.        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1063)
    5.        at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1358)
    6.        at java.util.concurrent.Semaphore.tryAcquire(Semaphore.java:415)
    7.        at com.unity3d.player.UnityPlayer.updateDisplayInternal(unavailable)
    8.        at com.unity3d.player.UnityPlayer.updateGLDisplay(unavailable)
    9.        at com.unity3d.player.UnityPlayer.access$1100(unavailable)
    10.        at com.unity3d.player.UnityPlayer$19.surfaceDestroyed(unavailable)
    11.        at android.view.SurfaceView.notifySurfaceDestroyed(SurfaceView.java:1943)
    12.        at android.view.SurfaceView.updateSurface(SurfaceView.java:1239)
    13.        at android.view.SurfaceView.setWindowStopped(SurfaceView.java:291)
    14.        at android.view.SurfaceView.surfaceDestroyed(SurfaceView.java:1767)
    15.        at android.view.ViewRootImpl.notifySurfaceDestroyed(ViewRootImpl.java:1891)
    16.        at android.view.ViewRootImpl.setWindowStopped(ViewRootImpl.java:1826)
    17.        at android.view.WindowManagerGlobal.setStoppedState(WindowManagerGlobal.java:700)
    18.        at android.app.Activity.performStop(Activity.java:8398)
    19.        at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:4981)
    20.        at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:4960)
    21.        at android.app.ActivityThread.handleStopActivity(ActivityThread.java:5034)
    22.        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:233)
    23.        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
    24.        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
    25.        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    26.        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2135)
    27.        at android.os.Handler.dispatchMessage(Handler.java:106)
    28.        at android.os.Looper.loop(Looper.java:236)
    29.        at android.app.ActivityThread.main(ActivityThread.java:8059)
    30.        at java.lang.reflect.Method.invoke(Native method)
    31.        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
    32.        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
     
    Last edited: Jan 26, 2022
  14. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,919
    Is it reproducible for you locally, also which device is this? Cheers
     
  15. ageana

    ageana

    Joined:
    Nov 6, 2013
    Posts:
    48
    I can't reproduce it locally, this is from Crashlytics.

    This is on Xiaomi Redmi Note 10 Pro

    upload_2022-1-26_12-6-44.png

    upload_2022-1-26_12-7-21.png
     
  16. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,919
    According to stacktrace, it seems to be happening when the application goes to background.

    So anyone experiencing this, can you try to do:
    * Start logcat and filter by your app https://docs.unity3d.com/Packages/com.unity.mobile.android-logcat@1.2/manual/PackageSelection.html
    * Start your game
    * Hit Home Button, thus putting the app to background
    * And then resume the app (Using phone system button Overview, shaped is square or with several lines)
    * Repeat this multiple times

    If all good, the app shouldn't crash, and you should see in logcat onPause/onResume messages for your app.
     
    AntonPetrov likes this.
  17. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,919
    I made this batch file for Windows which puts app to background and resumes it multiple times.
    • Modify Android SDK path in the script
    • Ensure your phone can be unlocked without pin or similar
    • Launch the application
    • In Unity, via logcat package, start filtering messages for your application
    • Run the batch script
      • It will lock/unlock the phone multiple times
      • After unlocking the phone your app should be the one which is running, if not, something's wrong
    • See if your app crashes.

    Code (CSharp):
    1. echo off
    2. SET ANDROID_SDK=G:\UnityInstalls\2022.1.0b1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK
    3.  
    4. SET ADB="%ANDROID_SDK%builds\platform-tools\adb.exe"
    5. SET TIME_BETWEEN_COMMANDS=1
    6.  
    7. for /l %%x in (1, 1, 100) do (
    8.    echo Starting Iteration %%x
    9.    timeout /T %TIME_BETWEEN_COMMANDS% /NOBREAK
    10.    call %ADB% shell input keyevent 6
    11.    timeout /T %TIME_BETWEEN_COMMANDS% /NOBREAK
    12.    call %ADB% shell input keyevent 82
    13.    timeout /T %TIME_BETWEEN_COMMANDS% /NOBREAK
    14.    call %ADB% shell input swipe 100 100 100 200
    15. )
    16.  
    17. echo Test Done
    18. pause
     
    Petr777 and AntonPetrov like this.
  18. AntonPetrov

    AntonPetrov

    Joined:
    Dec 27, 2013
    Posts:
    64
    Yes it crashes because
    Activity.onPause
    in
    main
    (as I can see from crash logs) is synchronized with
    UnityMain
    thread via a semaphore lock. Thus the
    main
    can be blocked by heavy operation in
    UnityMain
    thread. In our case it is a loading.

    2020.3.0f1
     
  19. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,919
    Loading ? Why are you loading, while the app tries to pause itself?
     
  20. AntonPetrov

    AntonPetrov

    Joined:
    Dec 27, 2013
    Posts:
    64
    1. We do loading at
    Unity Main
    . Currently it is a heavy synchronous routine but it is a script running at `Unity Main` and technically it must not cause an ANR.

    2. Player minimizes his app and it goes to background.
    UnityPlayerActivity.onPause
    is triggered by Android on the
    main
    thread.

    3. Currently I believe that
    UnityPlayerActivity.onPause
    waits for
    UnityMain
    which is busy loading our files.
    main
    is blocked - ANR is fired. That's it.
     
  21. MMatinahoDodreams

    MMatinahoDodreams

    Joined:
    Jan 24, 2020
    Posts:
    1
    Hey,
    just letting you know that we are seeing this ANR also with 2020.3.17f1 in Google play vitals. Unfortunately we dont have local repro case either.

    Top 5 offenders:
    1. Motorola moto g(30)25 (Qualcomm SM6115)
    16.2%

    2. Redmi Note 10 Qualcomm SM6150
    7.8%

    3. Motorola moto g(9) 7.8%
    Qualcomm SM6115

    4. Motorola moto g(9) power
    7.1%
    Qualcomm SM6115

    5. Lenovo K13 Note
    5.8%
    Qualcomm SM4350


    I tried this script in different scenes and couldnt get app to hang or crash.
     
  22. nemanjab

    nemanjab

    Joined:
    Jan 10, 2019
    Posts:
    12
    Has anyone resolved this issue?
     
  23. nemanjab

    nemanjab

    Joined:
    Jan 10, 2019
    Posts:
    12
    up
    Code (CSharp):
    1. main (timed waiting): tid=1 systid=2430
    2.        at sun.misc.Unsafe.park(Native method)
    3.        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:230)
    4.        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1063)
    5.        at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1358)
    6.        at java.util.concurrent.Semaphore.tryAcquire(Semaphore.java:415)
    7.        at com.unity3d.player.UnityPlayer.updateDisplayInternal(unavailable)
    8.        at com.unity3d.player.UnityPlayer.updateGLDisplay(unavailable)
    9.        at com.unity3d.player.UnityPlayer.access$1100(unavailable)
    10.        at com.unity3d.player.UnityPlayer$19.surfaceDestroyed(unavailable)
    11.        at android.view.SurfaceView.notifySurfaceDestroyed(SurfaceView.java:1830)
    12.        at android.view.SurfaceView.updateSurface(SurfaceView.java:1126)
    13.        at android.view.SurfaceView.setWindowStopped(SurfaceView.java:278)
    14.        at android.view.SurfaceView.surfaceDestroyed(SurfaceView.java:1654)
    15.        at android.view.ViewRootImpl.notifySurfaceDestroyed(ViewRootImpl.java:1880)
    16.        at android.view.ViewRootImpl.setWindowStopped(ViewRootImpl.java:1836)
    17.        at android.view.WindowManagerGlobal.setStoppedState(WindowManagerGlobal.java:694)
    18.        at android.app.Activity.performStop(Activity.java:8292)
    19.        at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:4915)
    20.        at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:4894)
    21.        at android.app.ActivityThread.handleStopActivity(ActivityThread.java:4968)
    22.        at android.app.servertransaction.StopActivityItem.execute(StopActivityItem.java:40)
    23.        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
    24.        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    25.        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2115)
    26.        at android.os.Handler.dispatchMessage(Handler.java:106)
    27.        at android.os.Looper.loop(Looper.java:250)
    28.        at android.app.ActivityThread.main(ActivityThread.java:7755)
    29.        at java.lang.reflect.Method.invoke(Native method)
    30.        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    31.        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)



    Also happening in background based on firebase
     
  24. nemanjab

    nemanjab

    Joined:
    Jan 10, 2019
    Posts:
    12
    @Tomas1856 any news on how to fix this ANR? what is causing it?
     
  25. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,919
    If you can reproduce it, we would love to get a bug report
     
  26. hba_infinity

    hba_infinity

    Joined:
    May 30, 2016
    Posts:
    49
    Hey @Thomas1856,

    We noticed that our game was getting a large amount of these issues relating to the unity3d.player.UnityPlayer.updateDisplayInternal showing up on our Google Play Developer Console for phones like the Motorola devices and the similar lists posted above. We went out and purchased one of the affected devices on Android 11, and was able to reproduce the ANR pretty reliably. At least in our case, it was due to the Application.Quit() function being used on these devices. The game would go into the background and look like it had quit correctly, but then the player was prompted with the "App not responding" popup which is triggering the ANR to show up on the Google Play Developer Console.

    We are using Unity 2020.3.26f1, and we have temporarily removed the quit functionality from the game only on those devices, and our ANR rate has dropped considerably.
     
  27. ing_unity

    ing_unity

    Joined:
    Nov 30, 2020
    Posts:
    12
    My project already use Screen.sleepTimeout = SleepTimeout.NeverSleep, but still have ANR problem in
    com.unity3d.player.UnityPlayer.updateDisplayInternal. So except remove Application.Quit() , Any further solution of this problem?
     
  28. livingtarget

    livingtarget

    Joined:
    Apr 21, 2015
    Posts:
    83
    Hilarious, I've seen this ANR for months on the dashboard and never considered it to be coming from the Application.Quit call. Could you tell me what specific device this repros on that you purchased?
     
  29. hba_infinity

    hba_infinity

    Joined:
    May 30, 2016
    Posts:
    49
    Hey @livingtarget,

    We purchased a Motorola G9 and upgraded it to Android 11, which seemed to be the version which was causing the most issues. The Application.Quit functionality has been a bit problematic in the past, so we did suspect it was a possible cause.

    For reference, we released an update in the past week which removed the Quit button on Motorola G, Motorola E and Motorola One devices running Android 11 or higher, which were some of the worst offenders for this issue. We are still seeing this error in our dashboard, but is only for a small subset of other devices. Our ANR rate has almost halved compared to the previous week.
    upload_2022-5-27_10-0-53.png
     
  30. livingtarget

    livingtarget

    Joined:
    Apr 21, 2015
    Posts:
    83
    @hba_infinity I took a bit more hard line approach and excluded all Motorola users and rolled it out to 50% of the users and found exactly what you told us. Basically removing the Application.Quit() caused this ANR in Firebase to go from 14 ANRs down to zero after like 5 or so days.

    So I mean that points almost exclusively to Application.Quit() causing an ANR for these devices when it probably shouldn't. I mean there is still a possibility we are doing too much in OnDisable() OnApplicationQuit(), but generally speaking I already tried to improve that and don't really know if there's too much more to optimise let alone hard to debug outside the editor.

    I mean it's almost impossible to create a repro for a case like this to submit to Unity though, so I don't know what they are going to do about it if anything.
     
    hba_infinity likes this.
  31. AntonPetrov

    AntonPetrov

    Joined:
    Dec 27, 2013
    Posts:
    64
    Hey guys! Here is my analysis and the solution we did implemented.

    The line
    java.util.concurrent.Semaphore.tryAcquire()
    in the call-stack indicates that `main` thread was waiting on a semaphore when ANR was triggered.

    But in the Unity code (you can check with Java decompiler) it is timed awaiting with 4 seconds timeout:
    Code (CSharp):
    1. if (!semaphore.tryAcquire(4L, TimeUnit.SECONDS))
    2.     ...
    3.  
    This 4 seconds timeout is Unity's protection against triggering an ANR because of main thread waiting on a semaphore for too long. But we still get this ANR :)

    Basically this ANR means that your Unity code takes at least 4 seconds PLUS there is some other code which executes on your
    Activity.onStop()
    because ANRs are triggered after 5 seconds. This can be any third-party SDK implementing
    Application.ActivityLifecycleCallbacks
    or something like that.

    In my case players were quitting a heavy scene and a lot of stuff was happening in
    OnApplicationPause()
    ,
    OnApplicationQuit()
    ,
    OnDisable()
    and
    OnDestroy()
    . Please note that all of these happen during a single frame so you can easily spend 4 seconds on some older device if you are qutting from the gameplay scene.

    What I did was when a user confirms that he or she wishes to quit the game:
    1. First, I do unload current heavy scene (switching to an empty scene). This does all heavy scene unloading as usual (we are not stopping the Android Activity yet)
    2. Only then I do call
    Application.Quit()
    and this wont take much time because we are on an empty scene now. But watch your DontDestroyOnLoads.

    And watch your third party SDKs. Keep only the bare minimum that you need. Most likely you cannot influence how they use
    Application.ActivityLifecycleCallbacks
    .
     
    Last edited: Jun 8, 2022
  32. chinhnt-imobility

    chinhnt-imobility

    Joined:
    Nov 2, 2018
    Posts:
    25
    i removed Application.Quit() but anr still remains high
     
  33. livingtarget

    livingtarget

    Joined:
    Apr 21, 2015
    Posts:
    83
    I saw this go down from 1.23% all the way down to 0.93% over 30 days. ANR rates are notorious in spiking at random intervals so the only way to check is to leave it up over a longer period of time.

    Also make sure you are actually seeing this exact same one. It should say ActivityThread.handleStopActivity in the stack trace.

    This is how I prevent our quit dialog box to show on Motorola devices. It's a pretty broad catch.
    Code (CSharp):
    1. #if UNITY_ANDROID
    2.         string deviceModel = SystemInfo.deviceModel;
    3.         if (!string.IsNullOrEmpty(deviceModel))
    4.         {
    5.             string deviceModelLower = deviceModel.ToLower();
    6.  
    7.             // just ignore all motorola devices to see if it makes a difference
    8.             if (deviceModelLower.Contains("moto"))
    9.             {
    10.                 // ignore calling Application.Quit() on certain devices
    11.                 return;
    12.             }
    13.         }
    14. #endif
    Also tried the unloading of the scene with this code and I'm still monitoring the results as it's not been live for a long time yet, but it seemed to have dropped to 0.76% in the last week.
    Code (CSharp):
    1. protected static void QuitApplication()
    2.     {
    3.         if (IsDelayedQuitEnabled())
    4.         {
    5.             Debug.Log("Delayed Quit");
    6.  
    7.             // ignore if already flagged as shutting down
    8.             if (GameClient.IsShuttingDown())
    9.                 return;
    10.  
    11.             // grab the current scene so we can unload it
    12.             Scene currentScene = SceneManager.GetActiveScene();
    13.  
    14.             // create an empty scene and make active
    15.             Scene scene = SceneManager.CreateScene("quit", new CreateSceneParameters(LocalPhysicsMode.None));
    16.             SceneManager.SetActiveScene(scene);
    17.  
    18.             // quit after unloading the scene
    19.             AsyncOperation asyncOperation = SceneManager.UnloadSceneAsync(currentScene);
    20.             asyncOperation.completed += (AsyncOperation op) => { Application.Quit(); };
    21.  
    22.             // try to dispose of some things, this could be moved before but here in case it throws exceptions
    23.             PreDispose();
    24.         }
    25.         else
    26.         {
    27.             Application.Quit();
    28.         }
    29.     }
    So this code is basically unloading the current active scene and hopefully cutting some time off the time it takes to quit the game. This does however add a delay where the game is still active before you are quitting, so it's a trade off and you may want to visually indicate that the game is actually going down.

    I would recommend to test this code, use it at your own risk and only apply this if you know for certain that you have this problem and for sure only target Android devices.
     
  34. chinhnt-imobility

    chinhnt-imobility

    Joined:
    Nov 2, 2018
    Posts:
    25
    Wow, nice idea. Thank
     
  35. vuquangdai23

    vuquangdai23

    Joined:
    Jan 27, 2021
    Posts:
    3
    Code (CSharp):
    1. public class GameClientServices {
    2.         public void Quit() {
    3. #if UNITY_ANDROID
    4.             try {
    5.                 PlayerPrefs.Save();
    6.                 new AndroidJavaClass("java.lang.System").CallStatic("exit", 0);
    7.             } catch (Exception ex) {
    8.                 Debug.LogError($"GameClientServices :: Quit has exception {ex}");
    9.             }
    10.  
    11. #else
    12.             UnityEngine.Application.Quit();
    13. #endif
    14.         }
    I've used code above to replace
    Code (CSharp):
    1. Application.Quit()
    and it worked
     
    anpk and chinhnt-imobility like this.
  36. chinhnt-imobility

    chinhnt-imobility

    Joined:
    Nov 2, 2018
    Posts:
    25
    I remove Application.Quit, unload heavy scene before quit the game but ANR still high.
    Maybe ANR come from Ads medition, I use ironSource Sdk, admob adapter, vungle, unity, meta, adcolony, applovin
     
    AntonPetrov likes this.
  37. chinhnt-imobility

    chinhnt-imobility

    Joined:
    Nov 2, 2018
    Posts:
    25
    up, still facing this issue.
     
    Qbit86 likes this.
  38. makcimbx

    makcimbx

    Joined:
    Aug 29, 2017
    Posts:
    12
    After add scene unload and after this Application.Quit, still facing this issue
     
  39. aboulianne_unity

    aboulianne_unity

    Joined:
    May 23, 2019
    Posts:
    1
    We deferred quitting specifically on motorola and xiaomi devices and our ANR rates dropped significantly, from 300-400 per day down to maybe 60 per day.

    What we did:
    If it's a "motorola" or "xiaomi" (SystemInfo.deviceModel contains the substring),
    - Show a placeholder (loading or Quitting UI)
    - Synchronously load an empty scene (that will unload existing scenes)
    - yield for one frame
    - call Application.Quit();

    The occurences aren't completely gone, but significantly enough to put us back into acceptable behaviour territory by a cozy margin.
     
  40. unity_W0vhibUNEtZH1g

    unity_W0vhibUNEtZH1g

    Joined:
    Nov 2, 2022
    Posts:
    5
    2020.3.40f1 still reproducing this problem


    Code (CSharp):
    1. sun.misc.Unsafe.park (Unsafe.java)
    2. java.util.concurrent.locks.LockSupport.parkNanos (LockSupport.java:230)
    3. java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos (AbstractQueuedSynchronizer.java:1063)
    4. java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos (AbstractQueuedSynchronizer.java:1358)
    5. java.util.concurrent.Semaphore.tryAcquire (Semaphore.java:415)
    6. com.unity3d.player.UnityPlayer.updateDisplayInternal (UnityPlayer.java)
    7. com.unity3d.player.UnityPlayer.updateGLDisplay (UnityPlayer.java)
    8. com.unity3d.player.UnityPlayer.access$1100 (UnityPlayer.java)
    9. com.unity3d.player.UnityPlayer$19.surfaceDestroyed (UnityPlayer.java)
    10. android.view.SurfaceView.notifySurfaceDestroyed (SurfaceView.java:1942)
    11. android.view.SurfaceView.updateSurface (SurfaceView.java:1238)
    12. android.view.SurfaceView.setWindowStopped (SurfaceView.java:291)
    13. android.view.SurfaceView.surfaceDestroyed (SurfaceView.java:1766)
    14. android.view.ViewRootImpl.notifySurfaceDestroyed (ViewRootImpl.java:1900)
    15. android.view.ViewRootImpl.setWindowStopped (ViewRootImpl.java:1835)
    16. android.view.WindowManagerGlobal.setStoppedState (WindowManagerGlobal.java:710)
    17. android.app.Activity.performStop (Activity.java:8378)
    18. android.app.ActivityThread.callActivityOnStop (ActivityThread.java:5064)
    19. android.app.ActivityThread.performStopActivityInner (ActivityThread.java:5043)
    20. android.app.ActivityThread.handleStopActivity (ActivityThread.java:5117)
    21. android.app.servertransaction.StopActivityItem.execute (StopActivityItem.java:40)
    22. android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:176)
    23. android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
    24. android.app.ActivityThread$H.handleMessage (ActivityThread.java:2172)
    25. android.os.Handler.dispatchMessage (Handler.java:106)
    26. android.os.Looper.loop (Looper.java:237)
    27. android.app.ActivityThread.main (ActivityThread.java:8163)
    28. java.lang.reflect.Method.invoke (Method.java)
    29. com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:656)
    30. com.android.internal.os.ZygoteInit.main (ZygoteInit.java:967)
     
  41. juan_homa

    juan_homa

    Joined:
    Aug 18, 2023
    Posts:
    25
  42. AntonPetrov

    AntonPetrov

    Joined:
    Dec 27, 2013
    Posts:
    64
    This is the main thread awaiting for unity thread to complete its execution on activity stop. The simplest reason could be some code does a lot of work in OnApplicationPause, OnApplicationFocus or OnApplicationQuit. Probably some synchronous I/O operation like a blocking web request.
     
  43. juan_homa

    juan_homa

    Joined:
    Aug 18, 2023
    Posts:
    25
    We indeed do some I/O operations on Application quit.

    Regarding the Application.Quit I've seen this:
    https://docs.unity3d.com/2023.3/Documentation/Manual/android-quit.html

    It says it's better to put the app in background on android than using the ApplicationQuit, "instead of Application.Quit. Activity.moveTaskToBack pauses the application and moves it to the background, which is closer to the standard Android application lifecycle than what Application.Quit"

    Would make sense to change Application.Quit into this to avoid this kind of ANR's ?

    Thanks!
     
    livingtarget likes this.