Android源代码分析实战:动态加载修复so库
2023-12-28 20:02:35
简介
俗话说,养兵千日,用兵一时。那么,学习源码分析到底有什么用呢?我们遇到的所有问题,都能通过分析源码解决吗?看似无法实现的功能,都能通过源码分析找到思路吗?这些都是之前无数次给大家洗脑的概念。今天,我们就来动手实战几次,看看源码分析在实际开发中的应用。
需求背景
之前还在有信时,我们做了一个分享功能,分享H5页面到微信朋友圈。由于是H5页面,所以需要动态加载一些so库。一开始,我们使用的是System.loadLibrary方法加载so库,但是发现了一个问题:如果so库不存在,就会抛出异常。这显然是不行的,因为我们不能保证用户手机上一定安装了so库。
分析源码
为了解决这个问题,我们需要分析一下System.loadLibrary方法的源码。在Android 8.0之前,System.loadLibrary方法的实现如下:
public static void loadLibrary(String libname) {
Runtime.getRuntime().loadLibrary(libname);
}
从源码中可以看出,System.loadLibrary方法实际上只是调用了Runtime.getRuntime().loadLibrary方法。而Runtime.getRuntime().loadLibrary方法的实现如下:
public void loadLibrary(String libname) {
if (is64Bit()) {
loadLibrary0("lib" + libname + ".so");
loadLibrary0("lib" + libname + ".so.64");
} else {
loadLibrary0("lib" + libname + ".so");
}
}
从源码中可以看出,Runtime.getRuntime().loadLibrary方法会尝试加载两个so库:一个是"lib" + libname + ".so",另一个是"lib" + libname + ".so.64"。如果64位so库存在,则只加载64位so库;如果32位so库存在,则只加载32位so库。
解决办法
知道了System.loadLibrary方法的源码后,我们就可以解决动态加载so库的问题了。我们可以自己写一个加载so库的方法,在这个方法中,我们先尝试加载64位so库,如果64位so库不存在,再尝试加载32位so库。这样,就可以保证无论用户手机上安装了哪个版本的so库,都可以成功加载。
public static void loadSoLibrary(String libname) {
try {
System.loadLibrary("lib" + libname + ".so.64");
} catch (UnsatisfiedLinkError e) {
System.loadLibrary("lib" + libname + ".so");
}
}
总结
通过分析Android源码,我们解决了动态加载so库的问题。这说明,源码分析在实际开发中是有用的。通过分析源码,我们可以深入了解Android系统底层原理,找到解决问题的办法。