SoLoader,android动态加载so库

Github:SoLoader https://github.com/facebook/SoLoader
Demo: The best SoLoader for android https://github.com/duqian291902259/DQ-Android-Labs

 

无需修改已有工程的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 Wec

更多相关文章

  1. Pycharm安装PyQt5的详细教程
  2. Android(安卓)命令行编译、打包生成apk文件
  3. Android异步加载图像小结 (含线程池,缓存方法)
  4. Android(安卓)Paging组件Demo
  5. Android(安卓)TabHost使用、动态加载内容
  6. 在android中policymanager
  7. Android(安卓)主流图片库Picasso Glide Fresco对比分析
  8. android手机客户端上传文件,java servlet服务器端接收并保存到服
  9. Android(安卓)获取存储卡路径和空间使用情况

随机推荐

  1. Android资源文件命名规则
  2. android方法数超过64k和Gradle编译OOM解
  3. android launchmode疑问?
  4. 深入理解Android消息处理系统
  5. Android(安卓)ANR发生原因总结
  6. UI组件:日历视图(CalendarView)
  7. android binder 进程间通信机制4-Service
  8. popupwindow的一些注意事项
  9. Android(安卓)特殊符号的转码大全
  10. Android(安卓)类代码防止反编译的办法