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

Android应用中C++原生库能否访问文件系统?Java如何传字符串到NDK库

问题原因排查
  • 硬编码路径不可靠:不同Android版本、多用户场景下,应用私有目录的路径不是固定格式,比如Android 10+部分设备私有目录路径会有调整,硬编码的/data/user/0/<App name>/files/otp.txt大概率会出现路径不匹配问题。
  • 权限不存在限制:同应用的原生库和Java层共享同一UID,天然有权限访问应用内部私有目录,不需要额外申请权限,所以你的问题基本可以确定是路径不匹配导致的。
更优的Java到C++字符串传递方案

JNI直接传参(优先推荐)

不需要中间文件做中转,直接在JNI调用时把字符串作为参数传入原生方法,无IO开销、逻辑最稳定:

  1. Java层声明带字符串参数的原生方法
public native String otp(String inputStr);
  1. C层对应的JNI方法直接接收字符串参数,转换为C/C可用的字符串格式即可
extern "C" JNIEXPORT jstring JNICALL
Java_你的包名_对应Activity名_otp(JNIEnv *env, jobject thiz, jstring input_str) {
    // jstring转std::string
    const char *c_str = env->GetStringUTFChars(input_str, nullptr);
    std::string otp_content(c_str);
    env->ReleaseStringUTFChars(input_str, c_str);
    
    // 此处执行原有业务逻辑
    
    // 若需要返回结果,转换为jstring返回即可
    return env->NewStringUTF(otp_content.c_str());
}

原生层全局缓存方案

如果你现有C代码的otp()函数签名已经固定、无法新增参数,可以在应用启动时先调用一个专属初始化JNI方法,把字符串传到C层存入全局变量,后续otp()函数直接读取全局变量即可:

#include <string>
// 全局缓存传入的字符串
static std::string g_otp_str;

// 初始化用的JNI方法,Java层启动时调用传入目标字符串
extern "C" JNIEXPORT void JNICALL
Java_你的包名_对应Activity名_setOtpContent(JNIEnv *env, jobject thiz, jstring input_str) {
    const char *c_str = env->GetStringUTFChars(input_str, nullptr);
    g_otp_str = std::string(c_str);
    env->ReleaseStringUTFChars(input_str, c_str);
}

// 原有otp函数直接读全局变量
const char* otp() {
    return g_otp_str.c_str();
}

修复原文件方案

如果一定要用文件中转的方案,不要硬编码路径:Java层调用getFilesDir().getAbsolutePath()拿到当前设备的正确私有目录路径,拼接文件名后通过JNI传入C++层,替换掉编译时硬编码的WORD_FILE宏即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:30:05