JNI DETECTED ERROR IN APPLICATION: unexpected jboolean value: 102
-
value
的类型为bool
- 当
value
的值为102时,代码全部报错unexpected jboolean value: unexpected jboolean value: 102
-
SetBooleanField
函数为void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
。第三个参数接受类型为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编译器优化导致
//运行崩溃:unexpected jboolean value: unexpected jboolean value: 102
if (value) {
env->SetBooleanField(jObj, fieldID, JNI_TRUE);
} else {
env->SetBooleanField(jObj, fieldID, JNI_FALSE);
}
- 以下代码没有报错,说明阻止了C编译器优化。
//运行成功
if (value) {
LOGD("111");
env->SetBooleanField(jObj, fieldID, JNI_TRUE);
LOGD("222");
} else {
LOGD("333");
env->SetBooleanField(jObj, fieldID, JNI_FALSE);
LOGD("444");
}
结论:
C编译器优化等级设置的是 -O3
,bool2jboolean
被优化了
在使用 JNI(Java Native Interface)进行开发时,正确配置编译器优化参数是非常重要的,尤其是为了避免由于优化导致的意料之外的行为。以下是如何在不同的构建工具中设置编译器优化参数的方法:
- CMake
如果你使用的是 CMake 构建工具,可以在 CMakeLists.txt 文件中设置编译器优化级别:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置编译器优化级别
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") # O2 为适度优化
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") # O2 为适度优化
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 构建工具,可以在 Application.mk 文件中设置编译器优化级别:
APP_OPTIM := debug # 或者 release
然后在 Android.mk 文件中可以进一步细化编译器标志:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myjni
LOCAL_SRC_FILES := src/main/cpp/myjni.cpp
LOCAL_CFLAGS := -O2 # 设置优化级别
LOCAL_LDLIBS := -llog # 添加必要的链接库
include $(BUILD_SHARED_LIBRARY)
- Gradle
如果你使用的是 Gradle 构建工具,可以在 build.gradle 文件中设置编译器优化级别:
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 文件中设置优化标志:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置编译器优化级别
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") # O2 为适度优化
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") # O2 为适度优化
add_library(myjni SHARED src/main/cpp/myjni.cpp)
find_package(OpenJDK REQUIRED)
include_directories(${JAVA_INCLUDE_DIRS})
target_link_libraries(myjni ${JAVA_LIBRARIES})
选择优化级别
-
-O0
:不进行优化,便于调试。 -
-O1
:基本优化。 -
-O2
:适度优化,是默认的优化级别。 -
-O3
:最大优化,可能会导致代码体积增大。