SoLoader是facebook出品的一款小巧的用于加载so库文件的开源项目,主要作用是自动检查和加载多个有依赖关系的so库文件。在Android平台下React-Native项目大量使用了动态链接库,即JNI技术,作为Java和Javascript两种程序语言之间的通信桥梁。
解压一个React-Native项目的安装包apk文件,我们可以看到一共有15个so库文件,其中libreactnativejni.so是JNI桥梁的入口。
而libreactnativejni.so又依赖于以下12个so文件:
libfb.so
libfbjni.so
libfolly_json.so
libjsc.so
libglog.so
libgnustl_shared.so
libandroid.so
liblog.so
libstdc++.so
libm.so
libc.so
libdl.so
其中,前6个是React-Native自身的动态链接库,后6个则是Android系统的动态链接库,所以如果想要加载libreactnativejni.so库,必须要先加载其依赖的这12个库文件。后6个系统的库文件是由系统预先加载到Dalvik虚拟机里面的,可以不用处理,但前6个必须手动预先加载!可是如果其中有库文件又依赖于其它的库文件,那么在加载其自身前又必须加载其依赖的库文件。
这样,其实就是一个递归加载依赖的过程,如果是由人工来维护这种依赖,首先极其繁琐,其次代码的可维护性也大大降低了。好在Android 4.3版本(包括)之后,会自动检查和加载依赖库,但是React-Native是兼容到Android 4.1版本的,所以SoLoader就是一种兼容4.3以下版本的技术解决方案。
SoLoader很轻巧,一种只有不到20个文件,可以直接用在任何的Android项目中,而不限于React-Native。
github开源地址:https://github.com/facebook/SoLoader
我们来研究以下SoLoader的实现原理。
首先SoLoader加载库文件之前,需要初始化,主要目的是将所有so库文件(系统+项目自身)所在目录预先全部收集起来,方面后面加载时查找。
来看一下com.facebook.soloader.SoLoader的init方法。
第一步:收集系统库文件
ArrayList<SoSource> soSources = new ArrayList<>();
String LD_LIBRARY_PATH = System.getenv("LD_LIBRARY_PATH");
if (LD_LIBRARY_PATH == null) {
LD_LIBRARY_PATH = "/vendor/lib:/system/lib";
}
String[] systemLibraryDirectories = LD_LIBRARY_PATH.split(