'surfaceDestroyed callback +' 没有 'surfaceDestroyed callback -'
'surfaceDestroyed callback +' without 'surfaceDestroyed callback -'
我正在调试使用 cocos2d-x 框架编写的 android 游戏。它必须与提供一些常见服务(如用户登录)的第三方库进行交互。该库将在我的游戏界面上绘制一些半透明图标。
然后在游戏回到桌面时点击home键会出现问题。如果我再次触摸游戏图标,游戏的最后一个快照会出现,但无法与之交互。
通常,当我最小化游戏时,eclipse 的 logcat 会打印如下:
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)
但不正常的是logcat如下:
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 +
看来'surfaceDestroyed callback+'和'surfaceDestroyed callback-'是一对。但是当其中一个错过时我找不到问题...
我找到问题的原因了。
第三方库是异步实现的,每个应用接口需要一个回调函数。我从android主线程(也叫UI线程)调用它的接口,但是回调函数是在另一个线程而不是主线程中执行的。所以我不能在回调函数中做 UI 事情。
为了知道库的调用完成并改变游戏UI,我在调用库的接口之前设置了一个标志变量,并在回调函数中更改变量。然后启动一个 'while(1)' 循环检查标志变量,直到它发生变化。
你注意到我调用库接口的主线程在接口调用后被阻塞了。这就是导致问题的原因。
为了解决这个问题,我使用定时器来监视标志变量而不是 'while(1)' 循环。
那我决定暂时放下这件事。但是在cocos2d-x框架中surface是如何创建和销毁的细节还有待我去研究。 :)
我正在调试使用 cocos2d-x 框架编写的 android 游戏。它必须与提供一些常见服务(如用户登录)的第三方库进行交互。该库将在我的游戏界面上绘制一些半透明图标。
然后在游戏回到桌面时点击home键会出现问题。如果我再次触摸游戏图标,游戏的最后一个快照会出现,但无法与之交互。
通常,当我最小化游戏时,eclipse 的 logcat 会打印如下:
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)
但不正常的是logcat如下:
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 +
看来'surfaceDestroyed callback+'和'surfaceDestroyed callback-'是一对。但是当其中一个错过时我找不到问题...
我找到问题的原因了。
第三方库是异步实现的,每个应用接口需要一个回调函数。我从android主线程(也叫UI线程)调用它的接口,但是回调函数是在另一个线程而不是主线程中执行的。所以我不能在回调函数中做 UI 事情。
为了知道库的调用完成并改变游戏UI,我在调用库的接口之前设置了一个标志变量,并在回调函数中更改变量。然后启动一个 'while(1)' 循环检查标志变量,直到它发生变化。
你注意到我调用库接口的主线程在接口调用后被阻塞了。这就是导致问题的原因。
为了解决这个问题,我使用定时器来监视标志变量而不是 'while(1)' 循环。
那我决定暂时放下这件事。但是在cocos2d-x框架中surface是如何创建和销毁的细节还有待我去研究。 :)