Android开发日常:使用JNI执行任何二进制文件

发布时间 - 2025-07-12 00:00:00    点击率:

android开发日常:使用jni执行任何二进制文件

什么是 JNI?

JNI,即 Java Native Interface 的缩写,通过使用 Java 本地接口编写程序,可以确保代码在不同平台上方便移植。从 Java 1.1 开始,JNI 标准成为 Java 平台的一部分,它允许 Java 代码与其他语言编写的代码进行交互。JNI 最初是为了本地已编译的语言,尤其是 C 和 C++ 设计的,但它并不妨碍你使用其他编程语言,只要调用约定受支持即可。使用 Java 与本地已编译的代码交互,通常会丧失平台的可移植性。然而,在某些情况下,这样做是可以接受的,甚至是必要的。例如,使用一些旧的库,与硬件或操作系统进行交互,或者为了提高程序的性能。JNI 标准至少保证本地代码能在任何 Java 虚拟机环境中工作。

在哪里见过?native 关键字。一个 native 方法就是一个 Java 调用非 Java 代码的接口。一个 native 方法是指该方法的实现由非 Java 语言实现,比如用 C 或 C++ 实现。在定义一个 native 方法时,不提供实现体(类似于定义一个 Java Interface),因为其实现体是由非 Java 语言在外部实现的。这主要是因为 Java 无法对操作系统底层进行操作,但可以通过 JNI(Java Native Interface)调用其他语言来实现底层的访问。

提出问题

很多时候使用 Kotlin 或 Java 开发 Android 时都离不开访问 /data/data/com.xxx.xxx/ 下的文件,由于 Linux 的不可控因素,在高版本 Android 系统中 Runtime.exec("su") 已经失效。那么该如何使用 root 权限去执行应用包下的二进制文件呢?

一些前提条件

使用 native 是少不了 NDK 包的,通过 Preferences(Settings) > Appearence & Behavior > System Settings > Android SDK 中的 SDK Tools 下载 NDK 与 CMake,具体如下图:

解决方案架构

在创建项目时使用 native C++ 模板进行创建;在 /src/main/ 包下会出现 cppjava 两种语言的核心包;进入 /src/main/cpp/native-lib.cpp 中,可以看到系统已自动生成了一个 C++ 函数;

System Fork

现在使用我们二年级学过的 C++ 知识来写一个 Linux 操作,让 system() 函数去执行:

#include 
#include 
#include 
#include 
#include 

void Shell(){ char shell[64]; sprintf(shell,"sh /data/data/com.example.jni/start.sh"); system(shell); return nullptr; }

这样我们就创建了一个 Shell() 方法。

JNI调用

Shell() 方法挂载到 JNI 实例中:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_jni_utils_shellUtil_execShell(JNIEnv env, jobject thiz) {
Shell();
}

回到需要调用的工具类(utils.shellUtil)中,写入调用:

static {
System.loadLibrary("native_lib");
}
private static native void shell(); //使用native关键字调取

这里的 System.loadLibrary("native_lib") 的意思为:调用你 build 之后生成的 libnative_lib.so SO库。

so库在哪里

编写完 C++ native lib 之后进行 build 操作可以在文件目录 /build/intermediates/merged_native_libs/debug/out/lib 下找到对应不同操作系统的 so 库文件。将它们复制到你的 libs(与 src 同级目录) 下后再 run 你的项目即可完成调用。

多线程

至此,已经完成了 native 库的编写与运行,你应该对 JNI 也有了一定的了解。但很多情况下我们不希望 被运行的二进制文件 阻碍 安卓主线程,这时候,需要使用到多线程对二进制文件的运行进行处理。我们可以在 native-lib.cpp 中这样处理:

#include 

include

include

include

include

include

void* Shell(){ char shell[64]; //fork拷贝 sprintf(shell,"sh /data/data/com.example.jni/start.sh"); system(shell); return nullptr; }

extern "C" JNIEXPORT void JNICALL Java_com_example_jni_utils_shellUtil_execShell(JNIEnv env, jobject thiz) { //创建线程id pthread_t tid; //启动线程 pthread_create( &tid, nullptr, reinterpret_cast>(Shell), nullptr ); }

通过 pthread 函数库进行线程处理,这样就保障了安卓应用主线程的线程安全,与并行的效率。

如何停止线程?管道通信

我们在小学三年级的 Linux操作系统 课程中已经知道了 system() 命令的执行过程是 fork子进程 执行二进制,这样就带来一个问题:我的二进制文件需要指定一个配置来启动的话就读取不到被设定为 read only 的文件夹内的资源。

如何解决?我也不会,希望有大佬能指点江山。


# java  # linux  # 操作系统  # 工具  # ai  # c++  # linux操作系统 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 网站制作软件有哪些,制图软件有哪些?  Laravel如何使用Blade模板引擎?(完整语法和示例)  JavaScript如何实现音频处理_Web Audio API如何工作?  如何用景安虚拟主机手机版绑定域名建站?  新三国志曹操传主线渭水交兵攻略  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  如何自定义建站之星网站的导航菜单样式?  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  微信h5制作网站有哪些,免费微信H5页面制作工具?  如何在阿里云服务器自主搭建网站?  如何在阿里云购买域名并搭建网站?  如何在新浪SAE免费搭建个人博客?  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  Laravel Blade模板引擎语法_Laravel Blade布局继承用法  Swift中循环语句中的转移语句 break 和 continue  Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives  利用vue写todolist单页应用  百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭  如何制作一个表白网站视频,关于勇敢表白的小标题?  Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程  zabbix利用python脚本发送报警邮件的方法  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Laravel怎么实现模型属性的自动加密  悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】  C++用Dijkstra(迪杰斯特拉)算法求最短路径  edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  开心动漫网站制作软件下载,十分开心动画为何停播?  微信小程序 scroll-view组件实现列表页实例代码  MySQL查询结果复制到新表的方法(更新、插入)  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  微信小程序 配置文件详细介绍  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  如何在云虚拟主机上快速搭建个人网站?  免费视频制作网站,更新又快又好的免费电影网站?  网站图片在线制作软件,怎么在图片上做链接?  Laravel如何为API生成Swagger或OpenAPI文档  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  网站优化排名时,需要考虑哪些问题呢?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  LinuxShell函数封装方法_脚本复用设计思路【教程】