Android中如何通过Process p = Runtime.getRuntime().exec("su")运行Java或C代码?
su进程运行自定义Java/C代码的问题 我明白你的痛点——用su启动了root进程,但只能敲终端命令,没法直接跑自己的业务代码,这确实有点受限。其实核心问题是:su启动的是一个独立的shell进程,它和你的App主进程完全隔离,没有加载App的Dalvik/ART虚拟机环境,所以没法直接执行你的Java代码;但咱们有几个可行的方案绕开这个限制:
方案一:把需要root权限的逻辑做成独立C/C++可执行文件
这是最常用也最稳定的方式,因为su进程可以直接执行系统级的二进制可执行文件:
编写并编译C/C++代码
用NDK编写需要root权限的逻辑(比如修改系统文件、操作/dev设备等),然后在构建脚本里配置生成可执行文件(不是普通的.so库)。比如在CMakeLists.txt里这样配置:add_executable(root_task src/main/cpp/root_task.cpp ) target_link_libraries(root_task log android )部署可执行文件
把编译好的root_task放到App的assets目录,在App启动时复制到私有目录(比如/data/data/com.your.package/files/),然后给它添加可执行权限:// 复制文件到私有目录 InputStream is = getAssets().open("root_task"); File outputFile = new File(getFilesDir(), "root_task"); FileOutputStream os = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) != -1) { os.write(buffer, 0, length); } is.close(); os.close(); // 添加可执行权限 outputFile.setExecutable(true);通过su调用
现在就可以用su启动这个可执行文件了,还能通过标准输入输出传递参数或获取结果:Process process = Runtime.getRuntime().exec(new String[]{ "su", "-c", outputFile.getAbsolutePath() + " 参数1 参数2" }); // 读取输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { // 处理输出内容 } process.waitFor();
方案二:用app_process运行Java代码
如果你更倾向于用Java实现root逻辑,可以借助Android系统的app_process工具——它是系统用来启动应用进程的入口,可以加载指定的Java类并执行main方法:
编写独立Java类
写一个不含App上下文依赖的Java类,比如:public class RootJavaTask { public static void main(String[] args) { // 这里写需要root权限的逻辑,比如修改系统文件 try { Process process = Runtime.getRuntime().exec("chmod 777 /system/etc/hosts"); process.waitFor(); } catch (Exception e) { e.printStackTrace(); } } }通过su调用app_process
用su启动app_process并指定要执行的类,注意要传入类的完整包名:Process process = Runtime.getRuntime().exec(new String[]{ "su", "-c", "app_process /system/bin com.your.package.RootJavaTask" }); // 处理输入输出和进程状态👉 注意:这个类不能依赖App的资源或上下文,因为它运行在独立的进程里,没有加载你的App APK环境,所有操作都要用绝对路径。
方案三:通过Shell脚本间接调用
如果你的逻辑比较复杂,比如需要先做一些环境准备、权限检查,可以写一个Shell脚本,把调用可执行文件或app_process的逻辑放到脚本里,然后通过su执行脚本:
编写脚本(比如
root_script.sh)#!/system/bin/sh # 检查是否有root权限 if [ $(id -u) -ne 0 ]; then echo "Not root" exit 1 fi # 调用你的可执行文件 /data/data/com.your.package/files/root_task部署并执行脚本
和可执行文件一样,把脚本复制到私有目录,添加可执行权限,然后用su执行:File scriptFile = new File(getFilesDir(), "root_script.sh"); // 复制脚本并加权限... Process process = Runtime.getRuntime().exec(new String[]{ "su", "-c", scriptFile.getAbsolutePath() });
关键注意事项
- 权限验证:每次调用
su后,最好检查进程的退出码(process.exitValue()),确认是否获取到了root权限; - 用户授权:如果用的是SuperSU或Magisk,第一次调用
su会弹出授权弹窗,要避免进程阻塞,最好处理好输入流; - 兼容性:不同Android版本的
app_process路径或参数可能有差异,多测试几个版本; - 安全性:root权限风险极高,不要把可执行文件或脚本暴露给其他App,也不要执行未验证的外部命令。
内容的提问来源于stack exchange,提问作者Egzy




