DQ-Android-Labs

Introduction: Magical modules with cool tech.The best dynamic so loader for android.
More: Author   ReportBugs   OfficialWebsite   
Tags:

Contains various magical modules with cool tech in the future.such as soloader....

New modules are being updated...

1,SoLoader,android 动态加载 so 库

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<File> libDirs = (List<File>) nativeLibraryDirectories.get(dexPathList);
            //去重
            if (libDirs == null) {
                libDirs = new ArrayList<>(2);
            }
            final Iterator<File> 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<File> systemLibDirs = (List<File>) 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);
        }

Android-SoLoader

下载 apk 体验一下吧: soloader-release.apk

Thanks

Welcome to contact me: duqian2010@gmail.com or Wechat:dusan2010

Apps
About Me
Google+: Trinea trinea
GitHub: Trinea