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來綜合分析。

其他的話,如果已經發布的產品,可以通過友盟的數據分析工具來解決問題。有時間我會專門來分享我們在使用友盟過程中的一些體會。
發佈了29 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章