点击登陆后,客户端需提取设备码提交到服务器,出现崩溃问题;
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下,挺有意思的打开方式,各位自己动手下吧。
下次碰到有意思的问题,继续分享给大家。