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下,挺有意思的打开方式,各位自己动手下吧。

下次碰到有意思的问题,继续分享给大家。

你可能感兴趣的:(android,jni,tab3,cocos2dx)