App Hotfix(热修复)详解
定义:
从广义的角度理解,大家都比较认同 Hotfix 是在移动端不需要重新发版,通过在线更新对版本 Bug 的修复。
现在比较流行的热修复技术分为三种:
一、使用JSPatch进行热修复:
Objective-C 是动态语言,OC上所有方法的调用/类的生成都通过 Objective-C Runtime 在运行时进行,我们可以通过类名和方法名反射得到相应的类和方法,也可以替换某个类的方法为新的实现,还可以新注册一个类,为类添加方法替换方法,通过这些即可实现动态修复 APP 技术。
JSPatch是一个在Github上的开源项目,JSPatch下载地址。JSPatch 的实现主要是通过 Objective-C的 runtime 原理,即利用JS传递字符串给OC,OC通过 Runtime 接口调用和替换OC方法。具体实现原理请参考作者的帖子:JSPatch 实现原理详解 (整改版)。
大体实现思路如下:
- 首先,开发者提供热修复脚本;
- 其次,要将脚本上传到后台,后台需要提供上传的操作页面;
- 然后,终端设备每次运行后请求获取最新的脚本文件;
- 最后,解析脚本文件,调用 JSPatch 引擎,执行脚本文件并修复;
1、开发者提供热修复脚本:
脚本的书写:
脚本书写也很简单,先用Objective-C将要需要更改的代码改好,然后根据需要修改的代码更改成js代码即可,具体书写方法请参照 JSPatch使用说明,或者使用上面提供的OC转JS工具。
例如:
OBjective-C代码,这里是需要修改的内容。
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
/** 该代码在上线后的项目里面并没有
* 即在 APP 上线后又临时修改的。
* 添加或者修改我们需要改动代码,如无需改动,该方法不变,此处拿修改标题做测试,可以做很堵其他操作;
*/
self.title = @"Welcome to use JSPatchDemo";
}
/**
* 省略其他代码
*/
@end
javascript代码:JS 属于链式语法,相信很多人都会,可以查看 JSPatch 的语法规则自己写,也可以通过OC转JS工具将上面的代码转换成JS 代码
defineClass('ViewController', {
viewDidLoad: function() {
self.super().viewDidLoad();
/** 该代码在上线后的项目里面并没有
* 即在 APP 上线后又临时修改的。
* 添加或者修改我们需要改动代码,如无需改动,该方法不变,此处拿修改标题做测试,可以做很堵其他操作;
*/
self.setTitle("Welcome to use JSPatchDemo");
},
});
至此,热修复脚本已经编写完成。
2、要将脚本上传到后台,后台需要提供上传的操作页面:
此处需要后台配置,将上面已经写好的脚本放到服务器上面,并开发接口由APP 请求接口获取到脚本文件
3、终端设备每次运行后请求获取最新的脚本文件:
终端获取请求后台开发的接口,获取到脚本内容,可以根据当前版本与脚本编号判断当前脚本是否是最新脚本,如果是最新脚本,则执行脚本内容。
4、解析脚本文件,调用 JSPatch 引擎,执行脚本文件并修复:
首先将JSPatch添加到项目中
pod 'JSPatch'
然后导入头文件#import "JSPatch.h"
, 在程序启动的时候注册 JSPatch
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//此处作为演示,加载本地的 js 文件
//热修复功能一般是从服务器段请求下来,然后再经过版本判断等操作,再加载等。
NSString * jsPath = [[NSBundle mainBundle] pathForResource:@"JSFileName" ofType:@"js"];
//在 js 文件存在的情况下,调用 JSPatch,如果js 文件不存在,程序会崩溃。
if ([[NSFileManager defaultManager] fileExistsAtPath:jsPath] ) {
NSString *scriptPatch = [NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:nil];
[JPEngine startEngine];
[JPEngine evaluateScript:scriptPatch];
}
}
至此,利用JSPatch引擎进行 APP 热修复功能差不多就如此了,剩下的就是调试优化上诉各个环节。
二、使用ReactNative实现热修复:
ReactNative是facebook提供的一种开源框架,使用JS语法进行跨平台开发,深受开发者青睐。直接使用ReactNative实现热修复的好像不是很多,比较流行的是使用微软的CodePush。
这个是CodePush的官方网站地址,这个是CodePushGitHut地址。具体实现参考该博客,讲的特别详细,我就不具体讲解了。
三、使用Lua+Wax打补丁的方案实现热修复:
由于 lua热修复框架多年不更新,此处省略。