Cocos2dx 3.17.2游戏崩溃求助:附Play Console崩溃回溯信息
Cocos2dx 3.17.2 DemoGame 两类崩溃问题分析与解决方案
一、Java层 AbstractMethodError 崩溃
崩溃信息
Fatal Exception: java.lang.AbstractMethodError: abstract method “void android.content.pm.PackageManager$OnChecksumsReadyListener.onChecksumsReady(java.util.List)” at android.app.ApplicationPackageManager$2.onChecksumsReady(ApplicationPackageManager.java:1016) at android.content.pm.IOnChecksumsReadyListener$Stub.onTransact(IOnChecksumsReadyListener.java:87) at android.os.Binder.execTransactInternal(Binder.java:1220) at android.os.Binder.execTransact(Binder.java:1179)
原因分析
这是典型的Android SDK版本兼容性问题:
PackageManager.OnChecksumsReadyListener是Android 12(API 31)新增的系统接口,若游戏的targetSdkVersion设置为31或更高,但Cocos2dx 3.17.2的Android层代码未适配该接口的实现,低版本Android设备(11及以下)尝试调用这个抽象方法时,就会触发AbstractMethodError。- 也可能是集成的第三方SDK(如广告、统计类)使用了该接口却未做版本兼容处理。
解决方案
- 临时降低targetSdkVersion:若暂时不需要适配Android 12+特性,将
build.gradle中的targetSdkVersion改为30,避开该接口的强制适配要求。 - 升级Cocos2dx引擎:Cocos2dx 3.17.2是较旧版本,后续版本(如3.17.5+或更高3.x版本)已修复Android 12适配问题,升级引擎可彻底解决该兼容性bug。
- 排查第三方SDK:检查集成的第三方SDK是否强制要求高targetSdkVersion,替换或升级到兼容低版本系统的SDK版本。
二、Native层 Sequence::update 崩溃
崩溃信息
[libMyGame.so] cocos2d::Sequence::update(float) pid: 0, tid: 0 >>> com.company.DemoGame <<< backtrace: #00 pc 0x00000000002ac08c /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so #01 pc 0x00000000002e0f7d /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (cocos2d::Sequence::update(float)+278) #02 pc 0x00000000002e0f23 /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (cocos2d::Sequence::update(float)+188) #03 pc 0x00000000002e0f23 /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (cocos2d::Sequence::update(float)+188) #04 pc 0x00000000002e0a5d /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (cocos2d::ActionInterval::step(float)+112) #05 pc 0x0000000000392e93 /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (cocos2d::ActionManager::update(float)+94) #06 pc 0x00000000002e539b /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (std::__ndk1::function<void (float)>::operator()(float) const+18) #07 pc 0x000000000035d87b /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (cocos2d::Scheduler::update(float)+94) #08 pc 0x000000000034ff97 /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (cocos2d::Director::drawScene()+42) #09 pc 0x00000000003514a5 /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/lib/arm/libMyGame.so (cocos2d::Director::mainLoop()+44) #10 pc 0x000000000006cb37 /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/oat/arm/base.odex (org.cocos2dx.lib.Cocos2dxRenderer.nativeDeleteBackward [DEDUPED]+94) #11 pc 0x000000000006da4b /data/app/com.company.DemoGame-wFz3_4vUXhkLB6m5XdqJJQ==/oat/arm/base.odex (org.cocos2dx.lib.Cocos2dxRenderer.onDrawFrame+210) #12 pc 0x00000000009d7929 /system/framework/arm/boot-framework.oat (android.opengl.GLSurfaceView$GLThread.guardedRun+3040) #13 pc 0x00000000009d876d /system/framework/arm/boot-framework.oat (android.opengl.GLSurfaceView$GLThread.run+180) #14 pc 0x000000000042e975 /system/lib/libart.so (art_quick_invoke_stub_internal+68) #15 pc 0x0000000000401821 /system/lib/libart.so (art_quick_invoke_stub+224) #16 pc 0x00000000000a82b9 /system/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+136) #17 pc 0x000000000035e9cd /system/lib/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+52) #18 pc 0x000000000035f725 /system/lib/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue*)+320) #19 pc 0x0000000000381203 /system/lib/libart.so (art::Thread::CreateCallback(void*)+866) #20 pc 0x0000000000064d55 /system/lib/libc.so (__pthread_start(void*)+22) #21 pc 0x000000000001ec41 /system/lib/libc.so (__start_thread+24)
原因分析
栈帧显示cocos2d::Sequence::update(float)被反复调用,属于动作系统的递归死循环或野指针访问:
- 最常见的是创建Sequence动作时出现循环引用,比如Sequence内部包含了自身,导致update方法无限递归调用,最终栈溢出崩溃。
- 其次是动作绑定的节点已被释放(如调用
removeFromParentAndCleanup(true)),但ActionManager仍在执行该节点的Sequence动作,访问了已释放的内存。 - 也可能是重复给同一个节点添加了同一个Sequence动作,导致动作执行逻辑混乱。
解决方案
- 排查Sequence动作创建逻辑:检查所有创建Sequence的代码,确保没有循环引用(比如
Sequence::create(action1, sequenceSelf, nullptr)这类错误写法)。 - 同步动作与节点生命周期:在节点销毁时,必须调用
node->stopAllActions()或action->stop(),避免动作在节点释放后继续执行。 - 用符号表定位具体代码:使用NDK的
addr2line工具,结合编译生成的带符号信息的libMyGame.so,将崩溃地址0x00000000002ac08c转换为具体代码行,精准定位问题。 - 开启调试模式提前发现问题:开发阶段启用
CC_ENABLE_DEBUG=1,可更早发现动作系统的异常,比如无效动作、重复添加等问题。
内容的提问来源于stack exchange,提问作者agamer
相关产品推荐
相关产品推荐

