SoLoader,android动态加载so库
16lz
2021-01-23
SoLoader,android动态加载so库
Contains various magical modules with cool tech in the future.such as soloader…New modules are being updated…
Github–>: The best SoLoader for android
无需修改已有工程的so加载逻辑,支持so动态下发并安全加载的方案。
如果项目native库很多,还支持各种平台,为了减少apk size,so库动态下发,按需加载是不错的选择。比如x86库服务器下发,动态加载,瘦身效果将非常可观。但是采取常规load方式,改动有点大,底层jar包,第三库不好改加载路径吖。so follow me:
在应用启动的时,一次注入本地so路径path,待程序使用过程中so准备后安全加载。so库动态加载黑科技,安全可靠,线上验证,强烈推荐!注入路径后,加载so的姿势不变:
1,System.loadLibrary(soName); 无需改变系统load方法,注入路径后照常加载,推荐。
2,使用第三方库ReLinker,有so加载成功、失败的回调,安全加载不崩溃。
3,System.load(soAbsolutePath);传统方法指定so路径加载,不适合大项目和第三方lib,so下发加载不够灵活,不推荐。
Quik Start
下载demo,使用Android Studio打开soloader工程。
把自定义的native库path插入nativeLibraryDirectories最前面,即使安装包libs目录里面有同名的so,也优先加载指定路径的外部so。可参考插件化、热更新开源库了解其思想,部分代码。
private static void install(ClassLoader classLoader, File folder) throws Throwable { Field pathListField = ReflectUtil.findField(classLoader, "pathList"); Object dexPathList = pathListField.get(classLoader); Field nativeLibraryDirectories = ReflectUtil.findField(dexPathList, "nativeLibraryDirectories"); List libDirs = (List) nativeLibraryDirectories.get(dexPathList); //去重 if (libDirs == null) { libDirs = new ArrayList<>(2); } final Iterator libDirIt = libDirs.iterator(); while (libDirIt.hasNext()) { final File libDir = libDirIt.next(); if (folder.equals(libDir) || folder.equals(lastSoDir)) { libDirIt.remove(); Log.d(TAG, "dq libDirIt.remove()" + folder.getAbsolutePath()); break; } } libDirs.add(0, folder); //system/lib Field systemNativeLibraryDirectories = ReflectUtil.findField(dexPathList, "systemNativeLibraryDirectories"); List systemLibDirs = (List) systemNativeLibraryDirectories.get(dexPathList); //判空 if (systemLibDirs == null) { systemLibDirs = new ArrayList<>(2); } Log.d(TAG, "dq systemLibDirs,size=" + systemLibDirs.size()); Method makePathElements = ReflectUtil.findMethod(dexPathList, "makePathElements", List.class); libDirs.addAll(systemLibDirs); Object[] elements = (Object[]) makePathElements.invoke(dexPathList, libDirs); Field nativeLibraryPathElements = ReflectUtil.findField(dexPathList, "nativeLibraryPathElements"); nativeLibraryPathElements.setAccessible(true); nativeLibraryPathElements.set(dexPathList, elements); }
完整demo,请移步github,链接在文章最前面。
Thanks
Welcome to contact me: duqian2010@gmail.com or Wechat:dusan2010
更多相关文章
- Android 7.1.2(Android N) Activity-Window加载显示流程
- android左右滑动加载分页以及动态加载数据
- Android WebView加载H5音视频自动播放、关闭Activity停止播放
- 升级Android Studio3.1.3,gradel无法加载pom和类库
- Android新版Glide的RequestManager加载管理器
- 改变android虚拟机的存放路径
- Mac修改环境变量路径中带空格的处理
- Android 动态加载APK--代码安装、获取资源及Intent调用已安装apk