我正在构建一个使用Native服务二进制文件的应用程序。
现在我的要求是:
将本机服务二进制文件放在应用程序的assets文件夹中。
getExternalFilesDir(null)
)现在复制文件,我已经使用过:
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for (String filename : files) {
if (filename.equals("native-file")) { // native-file is the file name present is assets folder
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(getExternalFilesDir(null), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
break;
}
}
}
复制后执行文件我使用:
File sdCard = getExternalFilesDir(null); // directory where native file is placed
Process proc = Runtime.getRuntime().exec("sh -c shell " + sdCard.getAbsolutePath() + "/native-file "+ sdCard.getAbsolutePath() +"/native-file.log\" "); // command 1
proc = Runtime.getRuntime().exec("sh -c less " + sdCard.getAbsolutePath() +"/native-file.log\""); // command 2
的问题:
PS - 由于专有问题,我无法提供我的JNI文件。所以我想我们可以使用一个开源asl库。(有一个名为asl-native的本机文件)
答案 0 :(得分:2)
您当前的代码并不太远,但您需要注意一些细节:
/sdcard
的文件。但是,您可以在内部存储器中执行文件。因此,请使用getExternalFilesDir(null)
getFilesDir()
Runtime.getRuntime().exec("chmod 755 " + getFilesDir() + "/native-file").waitFor();
或尝试使用私有android.os.FileUtils
类(如https://stackoverflow.com/a/11408378/3115956中所述)。Process proc = Runtime.getRuntime().exec(getFilesDir() + "/native-file");
如果要从可执行文件中读取stdout / stderr输出(以验证它是否正确运行),您可以执行以下操作:这样:
InputStream stdout = proc.getInputStream();
InputStream stderr = proc.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
String line;
while ((line = br.readLine()) != null)
System.out.println("stdout: " + line);
br = new BufferedReader(new InputStreamReader(stderr));
while ((line = br.readLine()) != null)
System.out.println("stderr: " + line);
为了简化步骤1和2,并且为了避免必须自己处理本机二进制文件的不同体系结构,您可以重命名命令行可执行文件以匹配模式lib<something>.so
并将其放入{{1您项目中的目录。然后它将被APK打包程序选中,并像任何本机库一样打包。要执行它,您只需执行libs/<abi>