Search code examples
androidcocos2d-xglsurfaceview

'surfaceDestroyed callback +' without 'surfaceDestroyed callback -'


I'm debugging an android game writing with cocos2d-x framework. It has to interact with a third-party's library that provides some common servicess like user log in. The library will draws some half-transparent icon on my game surface.

Then something wrong will happen when I touch the home button in game back to desktop. And if I touch the game icon again, the last snapshot of the game will show up, but can not be interacted with.

Normally, when I minimize the game, the eclipse's logcat will print as bellow:

01-29 09:13:21.493: D/SdkActivity(21533): ==onPause==
01-29 09:13:21.494: D/ActivityThread(21533): ACT-AM_ON_PAUSE_CALLED ActivityRecord{4227d568 token=android.os.BinderProxy@42179470 {org.cocos2dx.simplegame.uc/cn.uc.gamesdk.SdkActivity}}
01-29 09:13:21.504: D/ActivityThread(21533): ACT-PAUSE_ACTIVITY handled : 1 / android.os.BinderProxy@42179470
01-29 09:13:21.506: V/PhoneWindow(21533): DecorView setVisiblity: visibility = 4 ,Parent =ViewRoot{41eb1ab8 org.cocos2dx.simplegame.uc/org.cocos2dx.simplegame.uc.SimpleGame,ident = 0}, this =com.android.internal.policy.impl.PhoneWindow$DecorView{41da5790 I.E..... R....... 0,0-720,1280}
01-29 09:13:21.506: D/ActivityThread(21533): ACT-HIDE_WINDOW handled : 0 / android.os.BinderProxy@41cf9818
01-29 09:13:21.521: I/SurfaceView(21533): updateWindow -- onWindowVisibilityChanged, visibility = 4
01-29 09:13:21.521: I/SurfaceView(21533): Changes: creating=false format=false size=false visible=true left=false top=false mUpdateWindowNeeded=false mReportDrawNeeded=false redrawNeeded=false forceSizeChanged=false mVisible=true mRequestedVisible=false
01-29 09:13:21.521: I/SurfaceView(21533): Cur surface: Surface(name=null)/@0x41da3990
01-29 09:13:21.526: I/SurfaceView(21533): New surface: Surface(name=null)/@0x41da3a60, vis=false, frame=Rect(0, 0 - 720, 1280)
01-29 09:13:21.526: I/SurfaceView(21533): Callback --> surfaceDestroyed
01-29 09:13:21.526: I/SurfaceView(21533): surfaceDestroyed callback +
01-29 09:13:21.526: I/SurfaceView(21533): surfaceDestroyed callback -
01-29 09:13:21.527: V/SurfaceView(21533): Layout: x=0 y=0 w=720 h=1280, frame=Rect(0, 0 - 720, 1280)
01-29 09:13:21.530: D/GraphicBuffer(21533): create handle(0x5de3b2c8) (w:720, h:1280, f:1)
01-29 09:13:21.532: D/OpenGLRenderer(21533): Flushing caches (mode 0)
01-29 09:13:21.532: D/GraphicBuffer(21533): close handle(0x626af840) (w:720 h:1280 f:1)
01-29 09:13:21.533: D/GraphicBuffer(21533): close handle(0x61ed99d8) (w:720 h:1280 f:1)
01-29 09:13:21.533: D/GraphicBuffer(21533): close handle(0x5de3b2c8) (w:720 h:1280 f:1)
01-29 09:13:21.542: I/SurfaceView(21533): updateWindow -- OnPreDrawListener, mHaveFrame = true
01-29 09:13:21.698: D/OpenGLRenderer(21533): Flushing caches (mode 0)
01-29 09:13:21.699: D/GraphicBuffer(21533): close handle(0x62879c20) (w:720 h:1280 f:1)
01-29 09:13:21.700: D/GraphicBuffer(21533): close handle(0x66fc8b40) (w:720 h:1280 f:1)
01-29 09:13:21.701: D/GraphicBuffer(21533): close handle(0x632cfc78) (w:720 h:1280 f:1)
01-29 09:13:21.702: D/GraphicBuffer(21533): close handle(0x632cff80) (w:720 h:1280 f:1)
01-29 09:13:21.718: W/IInputConnectionWrapper(21533): showStatusIcon on inactive InputConnection
01-29 09:13:21.731: I/SurfaceView(21533): updateWindow -- onWindowVisibilityChanged, visibility = 8
01-29 09:13:21.732: D/OpenGLRenderer(21533): Flushing caches (mode 0)
01-29 09:13:21.736: I/SurfaceView(21533): updateWindow -- OnPreDrawListener, mHaveFrame = true
01-29 09:13:21.737: D/OpenGLRenderer(21533): Flushing caches (mode 0)
...
01-29 09:13:22.162: I/SurfaceView(21533): updateWindow -- OnPreDrawListener, mHaveFrame = true
01-29 09:13:22.162: D/SdkActivity(21533): ==onSaveInstanceState==
01-29 09:13:22.163: D/SdkActivity(21533): ==onStop==
01-29 09:13:22.166: V/PhoneWindow(21533): DecorView setVisiblity: visibility = 4 ,Parent =ViewRoot{41d393e8 org.cocos2dx.simplegame.uc/cn.uc.gamesdk.SdkActivity,ident = 12}, this =com.android.internal.policy.impl.PhoneWindow$DecorView{421b4c40 I.E..... R....... 0,0-720,1280}
01-29 09:13:22.166: D/ActivityThread(21533): ACT-STOP_ACTIVITY_HIDE handled : 0 / android.os.BinderProxy@42179470
01-29 09:13:22.178: D/OpenGLRenderer(21533): Flushing caches (mode 0)

But abnormally, the logcat is as bellow:

01-29 09:11:27.378: D/SdkActivity(21256): ==onSaveInstanceState==
01-29 09:11:27.378: D/SdkActivity(21256): ==onPause==
01-29 09:11:27.378: D/ActivityThread(21256): ACT-AM_ON_PAUSE_CALLED ActivityRecord{42028fb0 token=android.os.BinderProxy@41f86658 {com.mf.sglm.uc/cn.uc.gamesdk.SdkActivity}}
01-29 09:11:27.390: D/ActivityThread(21256): ACT-PAUSE_ACTIVITY handled : 1 / android.os.BinderProxy@41f86658
01-29 09:11:27.391: V/PhoneWindow(21256): DecorView setVisiblity: visibility = 4 ,Parent =ViewRoot{41eacbd8 com.mf.sglm.uc/com.mf.sglm.uc.SGLM,ident = 0}, this =com.android.internal.policy.impl.PhoneWindow$DecorView{41da0858 I.E..... R.....I. 0,0-720,1280}
01-29 09:11:27.392: D/ActivityThread(21256): ACT-HIDE_WINDOW handled : 0 / android.os.BinderProxy@41cf52b0
01-29 09:11:27.394: I/SurfaceView(21256): updateWindow -- onWindowVisibilityChanged, visibility = 4
01-29 09:11:27.394: I/SurfaceView(21256): Changes: creating=false format=false size=false visible=true left=false top=false mUpdateWindowNeeded=false mReportDrawNeeded=false redrawNeeded=false forceSizeChanged=false mVisible=true mRequestedVisible=false
01-29 09:11:27.394: I/SurfaceView(21256): Cur surface: Surface(name=null)/@0x41d9e8a0
01-29 09:11:27.399: I/SurfaceView(21256): New surface: Surface(name=null)/@0x41d9e970, vis=false, frame=Rect(0, 0 - 720, 1280)
01-29 09:11:27.399: I/SurfaceView(21256): Callback --> surfaceDestroyed
01-29 09:11:27.399: I/SurfaceView(21256): surfaceDestroyed callback +

It seems that 'surfaceDestroyed callback+' and 'surfaceDestroyed callback-' are a couple. But I can't find what's wrong when one of them missed...


Solution

  • I got the reason for the problem.

    The third-party's library is implemented asynchronously which need a callback function for each application interface. I call its interface from android main thread(also called UI thread), but the callback function is executed in another thread instead of the main thread. So I can't do UI things in the callback function.

    In order to know that the library's call is finish and change the game UI, I set up a flag variable before calling the library's interface and change the variable in the callback function. Then start a 'while(1)' loop checking the flag variable until its change.

    You notice that the main thread from which I call the library's interface was blocked after the interface call. That is the reason that cause the problem.

    To solve the problem, I use a timer to watch the flag variable instead of the 'while(1)' loop.

    Then I decide to let this thing go for this moment. But the details like how is the surface be created and destroyed in the cocos2d-x framework are still left to study for me. :)