【问题标题】:Is there a way to close a dynamically loaded library in Android?有没有办法在 Android 中关闭动态加载的库?
【发布时间】:2013-04-22 14:54:47
【问题描述】:

作为非 Android 人员的序言(一些 Linux 人员可能通过此信息知道答案):

Android 中的每个应用程序都在 Dalvik 虚拟机的一个实例中运行。启动应用程序时,名为 ActivityManager 的实体会写入管道以通知另一个实体 Zygote 需要启动应用程序。 Zygote 是一个空白的 Dalvik VM 实例,预加载了库,在通过管道调用时,它会克隆自己,并且克隆会降低与要启动的应用程序关联的 Linux 用户的权限级别。这可以在启动应用程序时节省时间和内存 - 考虑重新加载所有库并每次都进行所有设置的替代方案。

我的问题是在 Zygote 中加载了一个特定的库,我想在这个特定的过程中关闭它,因为我想使用我自己的库版本。我已经将我的本机代码与我的 .so 文件链接起来,该文件被复制到适当的文件夹中,并在应用程序启动时通过 Java 层“System.load('xyz')”加载,但是当我的代码运行时,它正在调用原始系统库的功能,而不是我的。当我运行“cat /proc/NNNN/maps”时,我可以看到旧库和我的一样在内存中。

有没有办法在我的应用程序中关闭该特定库?如果没有,有没有办法确保对该库中函数的任何/每个调用都传递给我的版本而不是旧版本?

谢谢!

【问题讨论】:

  • “关闭”就像卸载以前加载的共享库一样?似乎没有办法。请参阅:groups.google.com/forum/?fromgroups=#!topic/android-ndk/…groups.google.com/forum/?fromgroups=#!topic/android-ndk/…
  • @MarsAtomic:这些帖子是关于卸载应用程序本身加载的库,这略有不同。如果您管理自己的dlopen() / dlclose() 呼叫而不是依赖System.load(),您实际上可以做到这一点。由于一切都在应用程序的控制之下,因此可以安全地进行。这确实适用于您希望在不重新启动应用程序(或者更可能是服务)的情况下更新共享库的情况,而这里的问题是关于覆盖系统的库副本。
  • 大家好!实际上,我想卸载 Zygote 中默认加载的库,以便我可以自己加载该库的不同版本(在我的 DVM 实例中),并让通常会转到原始库的调用转到我的。

标签: android linux shared-libraries dalvik


【解决方案1】:

在最好的情况下关闭共享库(使用dlclose())很棘手,因为它会取消映射库的代码。如果稍后调用该代码——可能是 C++ 析构函数——程序将立即崩溃。由于该库是由您的代码以外的代码加载的,因此在您取消映射该库时,完全有可能另一个线程正在执行该库中的代码,从而再次导致崩溃。

所以,不要那样做。 :-)

如果您可以将您的库版本构建为静态库并将其直接链接到您的代码中,您应该能够完全避免该问题。

FWIW,各种库(尤其是 SSL 和 ICU)都链接到 Dalvik,而不是由 zygote 显式加载,因此如果您尝试替换其中一个库,无论您是分叉的,您都将获得 /system/lib 版本是否来自合子。

【讨论】:

  • 嗨法登!谢谢!我同意不这样做。我使用了其他一些巧妙的内存技巧来直接从内存中取消映射,但我最终选择使用 dlopen() 自己打开它,然后使用 dlsym() 提取我需要的函数指针。这要可靠得多。
  • 另外,作为关于正确性的说明 - 如果您使用的是小型库和/或仅将它与一个应用程序一起使用,我会建议 fadden 的回答涉及使用静态库。我正在为自定义构建的 Android 构建一套应用程序,因此将其静态链接到 20 种不同的东西会很浪费,所以在这种情况下,请使用我的建议与 dlopen()/dlsym()/dlclose()!
  • FWIW,你的方法就是 JNI 有 UnregisterNatives 的原因——如果你用 dlsym() 找到的任何符号是本机方法实现,你可以在调用 dlclose() 之前取消注册它们。
  • @fadden 不知道这是否会成为话题,但 ICU 有一个 u_cleanup() 函数将清理其所有内存 - 假设资源没有被其他线程使用(因为你指出)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 2021-07-27
  • 1970-01-01
  • 2020-09-27
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多