AndFix原理
AndFix的原理就是方法的替换,把有bug的方法替换成补丁文件中的方法。
注:在Native层使用指针替换的方式替换bug方法,已达到修复bug的目的。
使用AndFix修复热修复的整体流程:
方法替换过程:
源码解析
解析源码从使用的方法一一解析。
在自定义Application中初始化PatchManger:
PatchManager mPatchManager = new PatchManager();
直接实例化了一个PatchManger实例对象,接下看PatchManager类源码:
public PatchManager(Context context) {
mContext = context;
mAndFixManager = new AndFixManager(mContext);//初始化AndFixManager
mPatchDir = new File(mContext.getFilesDir(), DIR);//初始化存放patch补丁文件的文件夹
mPatchs = new ConcurrentSkipListSet<Patch>();//初始化存在Patch类的集合,此类适合大并发
mLoaders = new ConcurrentHashMap<String, ClassLoader>();//初始化存放类对应的类加载器集合
}
然后看AndFixManager的初始化:
public AndFixManager(Context context) {
mContext = context;
mSupport = Compat.isSupport();//判断Android机型是否适支持AndFix
if (mSupport) {
mSecurityChecker = new SecurityChecker(mContext);//初始化签名判断类
mOptDir = new File(mContext.getFilesDir(), DIR);//初始化patch文件存放的文件夹
if (!mOptDir.exists() && !mOptDir.mkdirs()) {// make directory fail
mSupport = false;
Log.e(TAG, "opt dir create error.");
} else if (!mOptDir.isDirectory()) {// not directory
mOptDir.delete();//如果不是文件目录就删除
mSupport = false;
}
}
}
public static synchronized boolean isSupport() {//此处加了同步锁机制
if (isChecked)
return isSupport;
isChecked = true;
// not support alibaba's YunOs
boolean isYunOs = isYunOS();//判断系统是否是YunOs系统,YunOs系统是阿里巴巴的系统
boolean setup =AndFix.setup();//判断是Dalvik还是Art虚拟机,来注册Native方法
boolean isSupportSDKVersion = isSupportSDKVersion();//根据sdk版本判断是否支持
if (!isYunOs && setup && isSupportSDKVersion) {//根据上面三个boolean值判断是否支持
isSupport = true;
}
if (inBlackList()) {
isSupport = false;
}
return isSupport;
}
private static boolean isSupportSDKVersion() {
if (android.os.Build.VERSION.SDK_INT >= 8
&& android.os.Build.VERSION.SDK_INT <= 23) {
return true;
}
return false;
}
public static boolean setup() {
try {
final String vmVersion = System.getProperty("java.vm.version");
boolean isArt = vmVersion != null && vmVersion.startsWith("2");
int apilevel = Build.VERSION.SDK_INT;
return setup(isArt, apilevel);
} catch (Exception e) {
Log.e(TAG, "setup", e);
return false;
}
}
//签名机制的初始化过程
public SecurityChecker(Context context) {
mContext = context;
init(mContext);
}
//主要是获取当前应用的签名及其他信息,为了判断与patch文件的签名是否一致
private void init(Context context) {
try {
PackageManager pm = context.getPackageManager();
String packageName = context.getPackageName();
PackageInfo packageInfo = pm.getPackageInfo(packageName,
PackageManager.GET_SIGNATURES);
CertificateFactory c