如何在android 2.1上从sd卡加载jni?

发布于 2024-09-01 18:18:21 字数 639 浏览 8 评论 0原文

我想在运行时加载第三方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 then
System.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苏大泽ㄣ 2024-09-08 18:18:21

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().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文