cocos2dx項目在三星tab3設備碼獲取失敗的閃退問題及解決

具體動作:
點擊登陸後,客戶端需提取設備碼提交到服務器,出現崩潰問題;

logcat錯誤信息如下:

12-16 16:58:53.645: E/dalvikvm(19006): JNI ERROR (app bug): accessed stale weak global reference 0xffffffff (index 65535 in a table of size 0)
12-16 16:58:53.645: E/dalvikvm(19006): VM aborting
12-16 16:58:53.645: A/libc(19006): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 19021 (Thread-1317)


使用萬能的ndk-stack -sym 跟蹤

********** Crash dump: **********
Build fingerprint: 'samsung/lt01wifizc/lt01wifi:4.2.2/JDQ39/T310ZCUAMJ1:user/release-keys'
pid: 19006, tid: 19021, name: Thread-1317 >>> package name <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
Stack frame #00 pc 00045cd8 /system/lib/libdvm.so (dvmAbort+75)
Stack frame #01 pc 0002862c /system/lib/libdvm.so (IndirectRefTable::get(void*) const+336)
Stack frame #02 pc 0004a2a1 /system/lib/libdvm.so (dvmDecodeIndirectRef(Thread*, _jobject*)+132)
Stack frame #03 pc 0004b191 /system/lib/libdvm.so
Stack frame #04 pc 003b5ccc /data/app-lib/package name-1/libgame.so (_JNIEnv::GetStringUTFChars(_jstring*, unsigned char*)+48): Routine GetStringUTFChars in (null):0
Stack frame #05 pc 005f8110 /data/app-lib/package name/libgame.so: Routine jstring2string_ in /Users/chenxu/work/c++/cocos2d-x-2.1.4/work/appname/proj.android/../../../cocos2dx/platform/android/jni/JniHelper.cpp:174
Crash dump is completed


目標代碼:原因可能是拿不到imei,所以數值爲空;
//查看設備唯一碼

std::string NativeCallJni::getImei()
{
LoggerUtil::getLogger()->logInfo(__FUNCTION__);

std::string imeiStr = "";
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
{
JniMethodInfo mInfo;//定義Jni函數信息結構體
bool isHave = JniHelper::getStaticMethodInfo(mInfo,JNI_CLASS_PATH,"getIMEI","()Ljava/lang/String;");
if (isHave)
{
jstring imei = (jstring)mInfo.env->CallStaticObjectMethod(mInfo.classID,mInfo.methodID);
imeiStr = JniHelper::jstring2string(imei);
}
}
#endif
return imeiStr;
}


cocos2dx的JniHelper.cpp代碼

static string jstring2string_(jstring jstr)
{
if (jstr == NULL)
{
return "";
}

JNIEnv *env = 0;

if (! getEnv(&env))
{
return 0;
}

#此處報錯android4.0嚴格,如果輸入值爲空,則崩潰
const char* chars = env->GetStringUTFChars(jstr, NULL);
string ret(chars);
env->ReleaseStringUTFChars(jstr, chars);

return ret;
}
}


崩潰的原因應該明白了,就是在提取不到imei的情況下,
jstring imei = (jstring)mInfo.env->CallStaticObjectMethod(mInfo.classID,mInfo.methodID);
iemi = null的話調用
imeiStr = JniHelper::jstring2string(imei);
此處報錯android4.0嚴格,如果輸入值爲空,則崩潰

現在的解決辦法就是獲取一個能夠替代deviceid的其他的特徵碼。我這裏考慮採用cpu serial作爲唯一碼
具體代碼如下

private static String getIdentifierByCpu() {
String identifier = "";
String cmdStr = "cat /proc/cpuinfo";

Process process;
try {
process = Runtime.getRuntime().exec(cmdStr);
InputStreamReader reader = new InputStreamReader(
process.getInputStream());
LineNumberReader lineReader = new LineNumberReader(reader);
String line = "";
while ((line = lineReader.readLine()) != null) {
if (line.startsWith("Serial")) {
identifier = line.split(":")[1];
Log.i(TAG, identifier);
}
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
return identifier;
}



測試驗證通過。今天又瞭解一個通過linux 命令行獲取系統信息的方法,就是 Runtime.getRuntime().exec(cmd)

另外小技巧。tab3的debug模式,需要google下,挺有意思的打開方式,各位自己動手下吧。

下次碰到有意思的問題,繼續分享給大家。
發佈了29 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章