JNI DETECTED ERROR IN APPLICATION: unexpected jboolean value: 102
-
value
的類型為bool
- 當(dāng)
value
的值為102時滥搭,代碼全部報錯unexpected jboolean value: unexpected jboolean value: 102
-
SetBooleanField
函數(shù)為void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
三妈。第三個參數(shù)接受類型為jboolean
//運行崩潰:unexpected jboolean value: unexpected jboolean value: 102
env->SetBooleanField(jObj, fieldID, value? 1 : 0 );
//運行崩潰:unexpected jboolean value: unexpected jboolean value: 102
jboolean newValue = value? 1 : 0;
env->SetBooleanField(jObj, fieldID, newValue);
//運行崩潰:unexpected jboolean value: unexpected jboolean value: 102
jboolean newValue = JNI_TRUE;
if (value) {
newValue = JNI_TRUE;
env->SetBooleanField(jObj, fieldID, newValue);
} else {
newValue = JNI_FALSE;
env->SetBooleanField(jObj, fieldID, newValue);
}
- 懷疑是C編譯器優(yōu)化導(dǎo)致
//運行崩潰:unexpected jboolean value: unexpected jboolean value: 102
if (value) {
env->SetBooleanField(jObj, fieldID, JNI_TRUE);
} else {
env->SetBooleanField(jObj, fieldID, JNI_FALSE);
}
- 以下代碼沒有報錯孔飒,說明阻止了C編譯器優(yōu)化赠堵。
//運行成功
if (value) {
LOGD("111");
env->SetBooleanField(jObj, fieldID, JNI_TRUE);
LOGD("222");
} else {
LOGD("333");
env->SetBooleanField(jObj, fieldID, JNI_FALSE);
LOGD("444");
}
結(jié)論:
C編譯器優(yōu)化等級設(shè)置的是 -O3
银觅,bool2jboolean
被優(yōu)化了
在使用 JNI(Java Native Interface)進(jìn)行開發(fā)時,正確配置編譯器優(yōu)化參數(shù)是非常重要的扫沼,尤其是為了避免由于優(yōu)化導(dǎo)致的意料之外的行為江掩。以下是如何在不同的構(gòu)建工具中設(shè)置編譯器優(yōu)化參數(shù)的方法:
- CMake
如果你使用的是 CMake 構(gòu)建工具,可以在 CMakeLists.txt 文件中設(shè)置編譯器優(yōu)化級別:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 設(shè)置編譯器優(yōu)化級別
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") # O2 為適度優(yōu)化
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") # O2 為適度優(yōu)化
add_library(myjni SHARED src/main/cpp/myjni.cpp)
find_package(OpenJDK REQUIRED)
include_directories(${JAVA_INCLUDE_DIRS})
target_link_libraries(myjni ${JAVA_LIBRARIES})
- ndk-build
如果你使用的是 ndk-build 構(gòu)建工具核畴,可以在 Application.mk 文件中設(shè)置編譯器優(yōu)化級別:
APP_OPTIM := debug # 或者 release
然后在 Android.mk 文件中可以進(jìn)一步細(xì)化編譯器標(biāo)志:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myjni
LOCAL_SRC_FILES := src/main/cpp/myjni.cpp
LOCAL_CFLAGS := -O2 # 設(shè)置優(yōu)化級別
LOCAL_LDLIBS := -llog # 添加必要的鏈接庫
include $(BUILD_SHARED_LIBRARY)
- Gradle
如果你使用的是 Gradle 構(gòu)建工具膝但,可以在 build.gradle 文件中設(shè)置編譯器優(yōu)化級別:
apply plugin: 'com.android.library'
android {
compileSdkVersion 30
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
}
sourceSets {
main {
jni.srcDirs = ['src/main/cpp']
jniLibs.srcDir 'src/main/jniLibs'
}
}
externalNativeBuild {
cmake {
path 'src/main/cpp/CMakeLists.txt'
version '3.10.2'
arguments '-DANDROID_STL=c++_static', '-DCMAKE_BUILD_TYPE=Release' # 或者 Debug
}
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
}
externalNativeBuild {
cmake {
path 'src/main/cpp/CMakeLists.txt'
version '3.10.2'
arguments '-DANDROID_STL=c++_static', '-DCMAKE_BUILD_TYPE=Release' # 或者 Debug
}
}
在 CMakeLists.txt 文件中設(shè)置優(yōu)化標(biāo)志:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 設(shè)置編譯器優(yōu)化級別
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") # O2 為適度優(yōu)化
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") # O2 為適度優(yōu)化
add_library(myjni SHARED src/main/cpp/myjni.cpp)
find_package(OpenJDK REQUIRED)
include_directories(${JAVA_INCLUDE_DIRS})
target_link_libraries(myjni ${JAVA_LIBRARIES})
選擇優(yōu)化級別
-
-O0
:不進(jìn)行優(yōu)化,便于調(diào)試谤草。 -
-O1
:基本優(yōu)化跟束。 -
-O2
:適度優(yōu)化,是默認(rèn)的優(yōu)化級別丑孩。 -
-O3
:最大優(yōu)化冀宴,可能會導(dǎo)致代碼體積增大。