Android应用中ProcessBuilder无法运行jniLibs内.so文件问题
问题分析与解决
常见原因
ABI架构不匹配
错误日志显示路径指向/lib/arm64/libadb.so,但如果你的jniLibs目录下没有为arm64-v8a架构提供对应的libadb.so,或者Gradle配置未包含该架构,系统会找不到目标so文件。Android 10+执行权限限制
Android Q(API 29)及以后版本,系统默认禁止直接执行/data/app/xxx/lib/目录下的so文件,即便路径正确,也会触发"找不到文件"的错误(实际是权限限制导致无法执行)。文件权限不足
即便so文件存在,若没有可执行权限,Linux系统会返回类似"找不到文件"的错误码,这是系统权限校验的常规逻辑。路径拼接错误
直接拼接adbPath+command可能导致路径与参数连在一起(比如/libadb.sopair localhost:2334),虽你的错误日志中路径显示正常,但仍需规避这类拼接问题。
解决步骤
1. 确保ABI架构匹配
- 检查
jniLibs目录结构:针对arm64设备,需存在jniLibs/arm64-v8a/libadb.so;针对其他架构(如armeabi-v7a),也要对应放置so文件。 - 在Module级
build.gradle中配置对应ABI:android { defaultConfig { ndk { abiFilters 'arm64-v8a', 'armeabi-v7a' // 根据设备架构按需添加 } } }
2. 拷贝so到可执行目录并设置权限
Android 10+需将so文件拷贝到App私有可写目录(如files)才能执行:
private File getExecutableAdb() throws IOException { File adbFile = new File(getFilesDir(), "adb"); if (!adbFile.exists()) { // 从lib目录拷贝so到files目录 String libAdbPath = getApplicationInfo().nativeLibraryDir + File.separator + "libadb.so"; InputStream inputStream = new FileInputStream(libAdbPath); OutputStream outputStream = new FileOutputStream(adbFile); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, length); } inputStream.close(); outputStream.close(); // 设置可执行权限 adbFile.setExecutable(true); } return adbFile; }
3. 正确启动ProcessBuilder
使用参数分离的方式启动,避免路径拼接错误:
File adbExec = getExecutableAdb(); // 示例:执行pair命令 Process process = new ProcessBuilder(adbExec.getAbsolutePath(), "pair", "localhost:2334") .directory(getFilesDir()) .start();
4. 验证文件存在性
若仍报错,可先打印日志排查路径问题:
File adbLib = new File(getApplicationInfo().nativeLibraryDir + "/libadb.so"); Log.d("ADB", "Lib exists: " + adbLib.exists()); Log.d("ADB", "Lib path: " + adbLib.getAbsolutePath());
内容的提问来源于stack exchange,提问作者zaxunobi
相关产品推荐
相关产品推荐

