cocos2dx app产品版本更新启动崩溃问题及解决

cocos2dx app产品版本更新启动崩溃

具体log如下:
W/dalvikvm( 7931): threadid=12: thread exiting with uncaught exception (group=0x42048930)
E/AndroidRuntime( 7931): FATAL EXCEPTION: GLThread 12293
E/AndroidRuntime( 7931): java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
E/AndroidRuntime( 7931):  at android.app.SharedPreferencesImpl.getString(SharedPreferencesImpl.java:224)
E/AndroidRuntime( 7931):  at org.cocos2dx.lib.Cocos2dxHelper.getStringForKey(Cocos2dxHelper.java:302)
E/AndroidRuntime( 7931):  at org.cocos2dx.lib.Cocos2dxRenderer.nativeRender(Native Method)
E/AndroidRuntime( 7931):  at org.cocos2dx.lib.Cocos2dxRenderer.onDrawFrame(Cocos2dxRenderer.java:94)
E/AndroidRuntime( 7931):  at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1524)
E/AndroidRuntime( 7931):  at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)


通过./adb logcat运行,也可以看到上述的错误堆栈

ndk-stack -asy 查找真机上的bug,因为是安装在真机上,还看不出具体的错误;

从上面的log信息看,貌似要从SharedPerence读取一个错误数据类型,比如保存的是int, 但是外部当作string类型来读取,所以系统自动做了类型的转换,但是类型转换失败导致崩溃。

另外一个奇怪的情况下,全新安装可以正常运行,但是如果升级安装的话就会崩溃。为了验证猜测是否正确,在新版本安装后,通过android中删除应用的缓存和数据文件,结果可以正常运行。

具体步骤:1. 设置, 2. 应用程序 3. app名称 4. 清除数据

综合上面2点,应该是旧版本的代码SharedPerences保存了int类型,但是新版本尝试使用string方式来读取出来。

然后找到相关代码修复
旧版本的cpp代码
    int announcement_id = UserDefaultUtil::getIntForKey(KEY_ANNOUNCEMENT_ID);
    if (announcement_id != announcement.id) {
        setAnnouncementVisible(true);
        UserDefaultUtil::saveIntToXml(KEY_ANNOUNCEMENT_ID, announcement.id);
    }


错误代码: lua
  -- getStringForKey此处有错误,强行取出一个String(但是文件保存为int类型)
  if CCUserDefault:sharedUserDefault():getStringForKey(KEY_ANNOUNCEMENT_ID) ~= announcement_content["id"] then
                CCUserDefault:sharedUserDefault():setStringForKey(KEY_ANNOUNCEMENT_ID, announcement_content["id"])
                setAnnouncementVisible(pLayer, true)
            end


修复后代码:
if announcement_content["id"] then
            announcement_id = tonumber(announcement_content["id"]) + 1
            if CCUserDefault:sharedUserDefault():getIntForKey(KEY_ANNOUNCEMENT_ID) ~= announcement_id then
                CCUserDefault:sharedUserDefault():setIntForKey(KEY_ANNOUNCEMENT_ID, announcement_id)
                setAnnouncementVisible(pLayer, true)
            end
        end


而且比较奇怪的事情,同样的代码在ios平台上运营通过,看来ios的平台比较健壮,而android c++环境相对比较严格,如果出现类型无法匹配的话,就会崩溃。

最近经常碰到android平台崩溃问题。 推荐大家多看logcat, 另外掌握ndk-stack来综合分析。

其他的话,如果已经发布的产品,可以通过友盟的数据分析工具来解决问题。有时间我会专门来分享我们在使用友盟过程中的一些体会。

你可能感兴趣的:(C++,android,lua,cocos2dx)