C++調用Android函數彈出一個提示框中出現的問題總結
(1) 在Jni.cpp中使用了全域變數
JNIEnv *g_env;jobject g_object;
然後在第一個傳入了JNIEnv和jobject的函數中初始化了:
JNIEXPORT jstring JNICALL Java_com_example_cocos2dinput_MainActivity_getStringFromC(JNIEnv* env,jobject thiz){g_env=env;g_object=thiz;return env->NewStringUTF("callCMessageBox");}
出現下面的錯誤,程式崩潰!
09-15 13:25:14.569: E/dalvikvm(15269): JNI ERROR (app bug): attempt to use stale local reference 0x1e800001
原因是因為在JAVA JNI中,對象要全域變數就要給他保持全域引用(不知道是不是這樣說。。)。
使用
g_object=(jobject)(env->NewGlobalRef(thiz));
代碼修改為以下OK:
JNIEXPORT jstring JNICALL Java_com_example_cocos2dinput_MainActivity_getStringFromC(JNIEnv* env,jobject thiz){g_env=env;g_object=(jobject)(env->NewGlobalRef(thiz));return env->NewStringUTF("callCMessageBox");}
(2) 修改了上面的問題後又出現以下問題:
我在C++中調用Android彈出一個提示框,原來直接在Jni.cpp中不使用全域變數是一切OK的,但是使用了AndroidPlatform.cpp之後就使用了全域變數g_object、g_env,所以出現上面的問題,修複了上面問題1後,Android層又出問題了!!
public static Context mContext;mContext=this.getApplicationContext();public void showMessage(){Log.d("showMessage", "showMessage");AlertDialog.Builder builder=new Builder(mContext);builder.setTitle("C++調用Android");builder.setMessage("這是一個C++調用Android的例子");builder.show();}
問題出現在下面:
android.view.WindowManager$BadTokenException: Unable to add window — token null
導致報這個錯是在於new AlertDialog.Builder(mcontext),雖然這裡的參數是AlertDialog.Builder(Context context)但我們不能使用getApplicationContext()獲得的Context,而必須使用Activity,因為只有一個Activity才能添加一個表單。
代碼修改成下面後OK:
public static Context mContext;mContext=MainActivity.this;public void showMessage(){Log.d("showMessage", "showMessage");AlertDialog.Builder builder=new Builder(mContext);builder.setTitle("C++調用Android");builder.setMessage("這是一個C++調用Android的例子");builder.show();}