We got ANR Problem in Google Play

We’ve encountered several ANR (Application Not Responding) issues on Google Play, with the following output content. Has anyone else experienced similar problems?

com.google.androidgamesdk.GameActivity.onPauseNative

“main” tid=1 Native
#00 pc 0x000000000005c074 /apex/com.android.runtime/lib/bionic/libc.so (syscall+32)
#01 pc 0x000000000006180d /apex/com.android.runtime/lib/bionic/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+92)
#02 pc 0x00000000000a822b /apex/com.android.runtime/lib/bionic/libc.so (pthread_cond_timedwait+76)
#03 pc 0x0000000000773193 /data/app/~~PKN2hJTO5SaMO566aWeGlA==/com.magicgame.momskitchencrush-hWTbnwJhCMw_hC_qLaEQ_Q==/split_config.armeabi_v7a.apk!libcocos.so
at com.google.androidgamesdk.GameActivity.onPauseNative (GameActivity.java)
at com.google.androidgamesdk.GameActivity.onPause (GameActivity.java:261)
at com.cocos.lib.CocosActivity.onPause (CocosActivity.java:136)
at com.cocos.game.AppActivity.onPause (AppActivity.java:2809)
at android.app.Activity.performPause (Activity.java:8234)
at android.app.Instrumentation.callActivityOnPause (Instrumentation.java:1530)
at android.app.ActivityThread.performPauseActivityIfNeeded (ActivityThread.java:5072)
at android.app.ActivityThread.performPauseActivity (ActivityThread.java:5033)
at android.app.ActivityThread.handlePauseActivity (ActivityThread.java:4985)
at android.app.servertransaction.PauseActivityItem.execute (PauseActivityItem.java:47)
at android.app.servertransaction.ActivityTransactionItem.execute (ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2247)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:201)
at android.os.Looper.loop (Looper.java:288)
at android.app.ActivityThread.main (ActivityThread.java:7886)
at java.lang.reflect.Method.invoke (Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:568)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1045)

[split_config.arm64_v8a.apk] android_app_set_activity_state

“main” tid=1 Native
#00 pc 0x000000000004f670 /apex/com.android.runtime/lib64/bionic/libc.so (syscall+32)
#01 pc 0x0000000000054060 /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex+144)
#02 pc 0x00000000000c1208 /apex/com.android.runtime/lib64/bionic/libc.so (pthread_cond_timedwait+136)
#03 pc 0x0000000000c17974 /data/app/~~mACo8CW7KmrKLw6XeJ7MQA==/com.magicgame.momskitchencrush-PPoXFUMt6N3upRUTzGnkPg==/split_config.arm64_v8a.apk (android_app_set_activity_state+4096) (BuildId: c4ba318d4eb6a06602e9d6bbc0404a1e30ffe8ea)
at com.google.androidgamesdk.GameActivity.onResumeNative (GameActivity.java)
at com.google.androidgamesdk.GameActivity.onResume (GameActivity.java:267)
at com.cocos.lib.CocosActivity.onResume (CocosActivity.java:142)
at com.cocos.game.AppActivity.onResume (AppActivity.java:2761)
at android.app.Instrumentation.callActivityOnResume (Instrumentation.java:1531)
at android.app.Activity.performResume (Activity.java:8422)
at android.app.ActivityThread.performResumeActivity (ActivityThread.java:4833)
at android.app.ActivityThread.handleResumeActivity (ActivityThread.java:4877)
at android.app.servertransaction.ResumeActivityItem.execute (ResumeActivityItem.java:54)
at android.app.servertransaction.ActivityTransactionItem.execute (ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2345)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:201)
at android.os.Looper.loop (Looper.java:288)
at android.app.ActivityThread.main (ActivityThread.java:7941)
at java.lang.reflect.Method.invoke (Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:569)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1019)

We have also encountered the same problem. Did you found a solution for this?

Same for us:

No, I am currently using this version.
Cocos Creator Version: 3.7.2
Target SDK: 33

I searched the forum. It seems that version 3.8.2 and above also have this problem.

Could you please contact the users to ask them to record the game situation when the error occurs? Currently, we are unable to analyze the cause of the problem based on the error report.

Sorry, We can’t contact our users.

But after I commented like this. The ANR is decreased.

static void onPause_native(JNIEnv *env, jobject javaGameActivity,
jlong handle) {
LOG_TRACE(“onPause_native”);
/*if (handle != 0) {
NativeCode *code = (NativeCode )handle;
if (code->callbacks.onPause != NULL) {
code->callbacks.onPause(code);
}
}
/
}

What is the expected percentage of reduction?

We are currently at 2.07%, but should it be 0.47%?

This was mentioned by Google Play, which states: “Your 28-day user-perceived ANR (Application Not Responding) rate exceeds the bad behavior threshold of 0.47%. Your app is likely to be less discoverable on Google Play across all devices.”

This issue was caused by a bug in android_native_app_glue within AGDK that resulted in thread lock blockages when switching between the foreground and background(pthread_cond_timedwait), and it’s a widespread problem.

I’m unclear why Google hasn’t addressed it consistently.

We managed to resolve the issue by modifying android_native_app_glue and adding a stack structure to save the APP_CMD_PAUSE event of android_native_app_glue .
After nearly a month of observation, the ANR rate has dropped to just one third of its original rate.
Moving forward,I will consider pushing a PR to Cocos as soon as possible for them to assess whether to merge it into the engine.

On April 24th, we released a fix version, and you can see the comparison.

2 Likes

@haroel So, to what extent has this problem been resolved? I am currently using cocos creator version 3.8.1. Can you tell me which version the solution was solved in?

Is it possible to share more detailed know-how? We believe this issue is very urgent.

In your game, what is the approximate size of the audio files, how many can be played simultaneously, and what is the maximum number?

Are there logs from other threads when an ANR occurs?

@Azaratur @gandangf @quriouschirag @haroel @Lukeluo
Sure, here is the translation of the text into English:

We have implemented logic to monitor unresponsive programs for timeouts. Please refer to this PR. On Android, it may be necessary to change SIGUSR1 to SIGUSR2.

Explanation:

The provided text discusses a mechanism for monitoring the responsiveness of programs and handling timeouts. It suggests that the current implementation might utilize SIGUSR1 signals for timeout detection, and on Android platforms, it might be beneficial to switch to SIGUSR2 signals instead.

Timeout Monitoring and Stack Printing:

The text mentions that upon enabling timeout monitoring, the system will print C++ and TypeScript stacks when a timeout occurs. This provides valuable information for debugging and identifying unresponsive sections of the program.

Storing Stack Traces in Files:

If the need arises to store these stack traces in files, the text suggests two potential approaches:

  1. Modify dispatchScriptExecutionTimeout: This implies that the dispatchScriptExecutionTimeout function, which is likely responsible for handling timeout detection and stack printing, could be modified to include functionality for saving stack traces to files.
  2. Implement Stack Storage in TypeScript Callback: Alternatively, the stack storage logic could be implemented within the TypeScript callback that is invoked when a timeout occurs. This would provide more granular control over how and where stack traces are saved.