APK体积优化其中有一点涉及so库的动态加载。工作流程是在原始项目构建时不会把so库加入到apk文件中,而是在app运行过程中找到合适的时机, 通过网络把so库文件下载手机本地,从而减少apk的体积。随着现在app功能日益丰富,使用的三方so库增多,该流程的效果更加突出。 学习DEMO 运行DEMO方式:
- push你手机架构的So文件到手机
/data/data/com.modi.dynamic/files/dynamic_so/
文件目录下
public class System{
public static void loadLibrary(String libname) {
Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
}
private synchronized void loadLibrary0(ClassLoader loader, Class<?> callerClass, String libname) {
if (libname.indexOf((int)File.separatorChar) != -1) {
throw new UnsatisfiedLinkError(
"Directory separator should not appear in library name: " + libname);
}
String libraryName = libname;
if (loader != null && !(loader instanceof BootClassLoader)) {
String filename = loader.findLibrary(libraryName);//加载so库
//...
return;
}
}
}
public class BaseDexClassLoader{
@UnsupportedAppUsage
private final DexPathList pathList;
//...
@Override
public String findLibrary(String name) {
return pathList.findLibrary(name);
}
//...
}
DexPathList--API
public class DexPathList{
private final File[] nativeLibraryDirectories;
//...
public String findLibrary(String libraryName) {
String fileName = System.mapLibraryName(libraryName);
for (File directory : nativeLibraryDirectories) {
File file = new File(directory, fileName);
if (file.exists() && file.isFile() && file.canRead()) {
return file.getPath();
}
}
return null;
}
//...
}
不同的版本代码有一定的差别 系统的过程是通过classoader检查native目录是否存在so库然后进行加载,只要我们把自定义的path路径也加进来,是不是就可以了达到效果。这其实很classloader热修复差不多。