Android 3.0 ANR problem

Android 3.0 ANR problem
0.0 0

#1

Hello, I’m testing my application on Android 3.0 tablet (Acer Iconia Tab A500). And I got ANR (Application Not Responding) dialog after about 5 minutes application have been running. Could anyone explain how to solve this problem? What I need to looking for? In logcat i found the message, that file “/data/anr/traces.txt” was created, but I can’t find one on my tablet filesystem. As far as I understand cocos2dx game loop running not in main thread, so main thread must not be blocked - is it true?

P.s. on other device (HTC desire phone (Android 2.2)) I never got the ANR dialog.


#2

AFAIK, tablet of android is not stable. I don’t know what’s the problem. I have meeted the problem in xoom, and I searched by google, it seems it is the problem of android 3.0.


#3

But, I never seen this problem in other games, that i have been install on this device. Seems that the problem hides in code of application. May be in cocos2dx code, may be in my code - I don’t know at the moment.


#4

I think cocos2d-x is not problem, because we had developed a programe for sansumg tablet, and it works ok.


#5

I see, but i have not any idea how to detect this kind of problem in my code. Could you explain - where the code in scenes runs - in main application thread or not? AFAIU this article http://developer.android.com/guide/practices/design/responsiveness.html must not to be longtime operations in main application thread.


#6

I’ve got a cocos2d-x Android game out on the market and it is getting ANR errors. I don’t know if it is Android 3.0 related or not, but can anyone make sense of this ANR stack trace? Is the source of the problem in the main thread or the other thread calling Cocos2dxMusic.playBackgroundMusic ?

The only thing I think could be a problem with onPause is that when onPause is called, I copy approx 20 values from memory to CCUserDefault::sharedUserDefault(). The problem may be that class writes out the XML file every time a single value is changed. Maybe I need to write a version CCUserDefault that has a flush that can be called when done modifying the DOM (i.e. iPhone NSUserDefault synchronize.) Thoughts?

DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
“main” prio=5 tid=1 WAIT
| group=“main” sCount=1 dsCount=0 obj=0x40024248 self=0xcec8
| sysTid=6019 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=~~1345006432
| schedstat=
at java.lang.Object.wait
~~ waiting on <0x40691b90> (a android.opengl.GLSurfaceView$GLThreadManager)
at java.lang.Object.wait(Object.java:358)
at android.opengl.GLSurfaceView$GLThread.onPause(GLSurfaceView.java:1466)
at android.opengl.GLSurfaceView.onPause(GLSurfaceView.java:501)
at org.cocos2dx.lib.Cocos2dxGLSurfaceView.onPause(Cocos2dxGLSurfaceView.java:173)
at com.mycompany.mygame.mygame.onPause(mygame.java:60)
at android.app.Activity.performPause(Activity.java:3931)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1191)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2459)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2424)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2404)
at android.app.ActivityThread.access$1700(ActivityThread.java:124)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:975)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3806)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)

“Binder Thread #3” prio=5 tid=17 NATIVE
| group=“main” sCount=1 dsCount=0 obj=0x406b4830 self=0x348628
| sysTid=6168 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=3010200
| schedstat=( 7910000 23796000 104 )
at dalvik.system.NativeStart.run(Native Method)

“GLThread 17” prio=5 tid=15 NATIVE
| group=“main” sCount=1 dsCount=0 obj=0x40693068 self=0x2fccd0
| sysTid=6166 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=3229336
| schedstat=( 92853040000 34338097000 86295 )
at android.media.MediaPlayer.prepare(Native Method)
at org.cocos2dx.lib.Cocos2dxMusic.playBackgroundMusic(Cocos2dxMusic.java:59)
at org.cocos2dx.lib.Cocos2dxActivity.playBackgroundMusic(Cocos2dxActivity.java:390)
at org.cocos2dx.lib.Cocos2dxRenderer.nativeRender(Native Method)
at org.cocos2dx.lib.Cocos2dxRenderer.onDrawFrame(Cocos2dxRenderer.java:31)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1363)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118)

Any insights would help!


#7

I think it has problems w/ dualcore. Android manifest has dualcore enabled?


#8

I think you can remove your operation on onPause() and have a try.

BTW: Did you call c++ function on onPause()? If so, I think it is not a good way.
The engine has responsed onPause() of Cocos2dxGLSurfaceView, and send a message to renderer, then renderer
will call native code. After call, you can do your operation on CCApplication::applicationDidEnterBackground() and CCApplication::applicationWillEnterForeground().
Because renderer run on its own thread, it will not block the main thread.


#9

No, I’m letting applicationDidEnterBackground call the function. I’m starting to think that the OnPause() ANR is actually a symptom of the problem, not the problem itself. In other words, the game freezes for some reason, so the user hits the home button which calls onPause() which gets stuck (because the C*+ is not responding) and results in an ANR in onPause. I have no idea why/where/how this is happening but it seems rare and I guess that is the nature of Android and supporting 600* devices.


#10

Hello, resume this post, because I have a problem with a method JNI call with GLThread on Pause.

my code:

@ private static void sendNativeResponseOnOpenGLThread (final int responseCode, final int errorCode) {

Cocos2dxGLSurfaceView.getInstance().queueEvent(new Runnable() {
Override public void run() { MainAnctivity.nativeSetResponse(responseCode, errorCode); } }); }

But the method in the Runnable start when: onResume waiting for !mPaused (GLThread also paused)

thanks in advance
Don