如何在android 2.1上从sd卡加载jni?
我想在运行时加载第三方jni库。
我试过直接从SD卡加载。预计会失败。
我尝试将库从 sdcard 复制到 /data/data/app/,然后System.load(/data/data/app/libjni.so)
它可以在 HTC HERO 上运行,但在运行 Android 2.1 的 HTC Legend 上失败。 它在执行本机代码期间失败并写入日志无信息的堆栈跟踪 还有其他方法可以做到吗? 这是最好的代码,适用于 1.5(HTC Hero),但不适用于 2.1(HTC Legend)。
FileInputStream fis = new FileInputStream("/sdcard/libjni.so");
File nf = new File("/data/data/app/libjni.so");
FileOutputStream fos = new FileOutputStream(nf);
byte[] buf = new byte[2048];
int n;
while ((n = fis.read(buf)) > 0)
fos.write(buf, 0, n);
fis.close();
fos.close();
System.load("/data/data/app/libjni.so");
I want to load third-party jni library in runtime.
I've tried to load directly from sdcard. It expectedly failed.
I've tried to copy library from sdcard to /data/data/app/ and thenSystem.load(/data/data/app/libjni.so)
It works on HTC HERO, but fails on HTC Legend with Android 2.1.
it fails during execution of native code and write to log uninformative stack trace
Any other way to do it?
Thats the best piece of code, that works at 1.5(HTC Hero), but donot works on 2.1(HTC Legend).
FileInputStream fis = new FileInputStream("/sdcard/libjni.so");
File nf = new File("/data/data/app/libjni.so");
FileOutputStream fos = new FileOutputStream(nf);
byte[] buf = new byte[2048];
int n;
while ((n = fis.read(buf)) > 0)
fos.write(buf, 0, n);
fis.close();
fos.close();
System.load("/data/data/app/libjni.so");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Android 的动态加载器无法从 SD 卡的文件系统加载可执行代码,因为它被标记为不可执行,并且您无法从不可执行存储映射可执行内存页面。 (理论上,您可以手动将内容复制到可执行的匿名映射页面中,但这很丑陋。SD 上支持应用程序的 Android 版本会安装 SD 卡上文件中包含的可执行文件系统,但第三方应用程序无法写入这些文件)
但是您可以做的是将库写入内部存储中的可写位置 - 不是您没有写访问权限的 lib 目录,而是从 Context.getDir() 或 Context 找到的另一个目录.getFilesDir(),然后使用 System.load() 而不是 System.loadLibrary() 使用完整路径和 .so 文件名加载它。
Android's dynamic loader cannot load executable code from the sdcard's filesystem, because it is marked non-executable and you cannot map executable memory pages from non-executable storage. (In theory you could manually copy the contents into executable anonymous mapped pages, but that's ugly. Versions of android supporting apps on SD mount an executable file systems contained within a file on the sdcard, but a third party app can't write those)
But what you can do is write a library to a writable location in internal storage - not the lib directory to which you don't have write access, but another one found from Context.getDir() or Context.getFilesDir() and then load it using the full path and .so file name using System.load() instead of System.loadLibrary().