作为非Android用户的序言(一些Linux用户可能知道这个信息的答案):
Android中的每个应用程序都在Dalvik虚拟机的实例中运行。启动应用程序时,名为ActivityManager的实体会写入管道,以通知另一个实体Zygote需要启动应用程序。 Zygote是一个空白的Dalvik虚拟机实例,其中有预先加载的库,在通过管道召唤后,它会自行克隆,并且克隆将其权限级别降低到与要启动的应用程序关联的Linux用户。这可以在启动应用程序时节省时间和内存 - 考虑重新加载所有库并每次都进行所有设置的替代方案。
我的问题是在Zygote中加载了一个特定的库,我希望在这个特定的过程中关闭它,因为我想使用我自己的库版本。我已将我的本机代码与MY .so文件相关联,该文件被复制到一个正确的文件夹中,并在应用程序启动时通过Java层“System.load('xyz')”加载,但是当我的代码运行时,它正在调用原始系统库的功能而不是我的。当我运行“cat / proc / NNNN / maps”时,我可以看到旧库和我的内存一样。
有没有办法在我的应用程序中关闭该特定库?如果没有,有没有办法确保对该库中的函数的任何/每次调用都传递给MY版本而不是旧版本?
谢谢!
答案 0 :(得分:2)
在最好的情况下,关闭共享库(使用dlclose()
)很棘手,因为它将取消映射库的代码。如果稍后调用该代码 - 可能是C ++析构函数 - 程序将立即崩溃。由于库是由非您的代码加载的,因此在您取消映射时,另一个线程完全有可能在该库中执行代码,再次导致崩溃。
所以,不要这样做。 : - )
如果您可以将库的版本构建为静态库并将其直接链接到代码中,那么您应该能够完全避免这个问题。
FWIW,各种库(特别是SSL和ICU)链接到Dalvik,没有被zygote显式加载,所以如果你试图替换其中一个,你将得到/system/lib
版本,不管你是谁吗?是否与zygote分道扬。