You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11 JNI禁用fdsan时未声明函数编译问题如何解决

Android fdsan接口调用适配方案

编译错误修复

android_fdsan_set_error_level是Android 10(API 29)新增的系统接口,编译未找到标识符的问题可以通过两种方式解决:

方案1:修改编译配置(适合拆分独立库的场景)

在独立库的Android.mk中添加如下配置,指定编译时使用API 29及以上的NDK版本:

# 指定编译使用的SDK版本
LOCAL_SDK_VERSION := 29
# 指定NDK编译的API等级
LOCAL_NDK_API_LEVEL := 29
# 可选:限制该库仅支持Android 10及以上系统,避免低版本设备加载
LOCAL_MIN_SDK_VERSION := 29

配置完成后重新编译,即可正常识别fdsan相关接口。

方案2:添加函数弱声明(无需拆分库,兼容性更好)

不需要调整全局编译配置,直接在用到该接口的cpp文件头部添加弱引用声明即可,编译时不会报错,运行时会自动判断函数是否存在:

#include <android/api-level.h>

// 弱引用声明,低版本系统无该函数时指针为NULL
extern "C" void android_fdsan_set_error_level(uint32_t level) __attribute__((weak));
// 定义fdsan错误等级常量,和系统定义保持一致
#define ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE 2

运行时调用逻辑

非拆分库场景

直接在应用初始化的native逻辑中添加如下判断:

if (android_get_device_api_level() >= 30) {
    if (android_fdsan_set_error_level != nullptr) {
        android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
    }
}

拆分独立库场景

  • Java层加载so前先判断系统版本,仅Android 10及以上加载该独立库:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    System.loadLibrary("你的独立so库名称");
    // 仅Android 11及以上调用禁用fdsan的接口
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        FdsanUtil.disableFdsan();
    }
}
  • 独立库的native代码直接实现disableFdsan接口即可,无需额外判断函数存在性:
#include <android/fdsan.h>
#include <android/api-level.h>

extern "C" JNIEXPORT void JNICALL
Java_xxx_FdsanUtil_disableFdsan(JNIEnv *env, jclass clazz) {
    if(android_get_device_api_level()>=30) {
        android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
    }
}

内容的提问来源于stack exchange,提问作者Filipe Madureira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 10:18:03