轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/119547007
本文出自【趙彥軍的博客】
文章目錄
- JNI捕獲例外
- JNI拋出例外
JNI捕獲例外
如果 JNI 呼叫 java 代碼,Java 代碼發生發生例外,會發生什么情況
舉例:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(R.id.sample_text).setOnClickListener {
run()
}
}
external fun run()
/**
* 這個方法會發生例外
*/
fun sum() {
1 / 0
}
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
}
c++ 代碼實作:
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_run(JNIEnv *env, jobject thiz) {
jclass cls = env->GetObjectClass(thiz);
jmethodID jmethodId = env->GetMethodID(cls, "sum", "()V");
env->CallVoidMethod(thiz, jmethodId);
}
app 運行起來,會看到程式崩潰,日志如下:

那么如何在 JNI 中捕獲?其實很簡單
jthrowable ExceptionOccurred()
舉例如下:
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_run(JNIEnv *env, jobject thiz) {
jclass cls = env->GetObjectClass(thiz);
jmethodID jmethodId = env->GetMethodID(cls, "sum", "()V");
env->CallVoidMethod(thiz, jmethodId);
//捕獲例外
jthrowable throwable = env->ExceptionOccurred();
if (throwable) {
//如果有例外發生,輸出例外資訊
env->ExceptionDescribe();
//清除例外資訊,app就不會崩潰
env->ExceptionClear();
}
}
JNI拋出例外
在上面的章節中,我們學習了JNI 捕獲例外,并且清除了例外資訊,但是這樣做治標不治本,我們需要的是能夠捕獲到例外,并且拋出到 Java 層,
jint Throw(jthrowable obj)
舉例說明:
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_run(JNIEnv *env, jobject thiz) {
jclass cls = env->GetObjectClass(thiz);
jmethodID jmethodId = env->GetMethodID(cls, "sum", "()V");
env->CallVoidMethod(thiz, jmethodId);
//捕獲例外
jthrowable throwable = env->ExceptionOccurred();
if (throwable) {
//拋出例外
env->Throw(throwable);
}
}
Java 代碼如下:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(R.id.sample_text).setOnClickListener {
//捕獲例外
try {
run()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
external fun run()
/**
* 這個方法會發生例外
*/
fun sum() {
1 / 0
}
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
}
APP運行起來,我們看看效果:

可以看到我們已經在 Java 代碼中捕獲到了例外,
除此之外,我們還可以自定義例外,然后拋出,示例如下:
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_run(JNIEnv *env, jobject thiz) {
jclass cls = env->GetObjectClass(thiz);
jmethodID jmethodId = env->GetMethodID(cls, "sum", "()V");
env->CallVoidMethod(thiz, jmethodId);
//捕獲例外
jthrowable throwable = env->ExceptionOccurred();
if (throwable) {
//清除原有的例外
env->ExceptionClear();
//創建自定義例外,并拋出
jclass exception = env->FindClass("java/lang/Exception");
env->ThrowNew(exception, "jni發生例外了");
}
}
看看效果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/293201.html
標籤:其他
