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. Android异步加载图像小结 (含线程池,缓存方法)
  2. Android TabHost使用、动态加载内容
  3. Android 实现View中添加子元素的动态效果
  4. Android 获取存储卡路径和空间使用情况
  5. exp: 修改Android中strings.xml文件, 动态改变数据
  6. android 怎么实现启动页提前加载webView里的内容
  7. Android动态获取当前手机IP地址
  8. android listview 自动加载
  9. Android 加载服务器上的图片

随机推荐

  1. android中ListView的使用
  2. mono for android 学习记录
  3. Android拖动相片特效
  4. Android移动view动画问题
  5. Android(安卓)NDK APIs
  6. 挑战全网!最全Android面试知识点梳理。收
  7. Android将Service服务打包jar供三方调用
  8. Android之HttpsURLConnection访问网络(an
  9. 跟着第二行代码回顾Android--持久化技术
  10. Android(安卓)intent intent-filter 分类