最近一两年Android插件化热更新此起彼伏,也许Android的开发者也希望有朝一日,来颠覆频繁的去更新版本,而像web前端一样,更改了代码立马生效的效果。确实,如果已经上线的版本,突然有了bug,按照现有模式,开发者不得不去解决bug,然后再经测试无误后,再发布到应用市场,这一系列的操作,不仅浪费时间,而且也会影响用户的使用体验。
最近热更新的开源项目有很多,比如Dexposed,AndFix,ClassLoader,nuwa等等,具体相关的介绍,网上随便一搜,文章都有很多
这里我只简单简述一下AndFix的具体使用。
第一步依赖:在自己项目中build.gradle文件下:dependencies { compile 'com.alipay.euler:andfix:0.3.1@aar'}
第二不引入所需要的so文件
第三步,在Application里onCreate方法里进行判断是否进行初始化,也就是说得有一个接口来定义一个开关,当线上的版本有bug的时候,我们把这个开关打开,来进行热更新,否则就处在关闭状态下。
最近热更新的开源项目有很多,比如Dexposed,AndFix,ClassLoader,nuwa等等,具体相关的介绍,网上随便一搜,文章都有很多
这里我只简单简述一下AndFix的具体使用。
第一步依赖:在自己项目中build.gradle文件下:dependencies { compile 'com.alipay.euler:andfix:0.3.1@aar'}
第二不引入所需要的so文件
第三步,在Application里onCreate方法里进行判断是否进行初始化,也就是说得有一个接口来定义一个开关,当线上的版本有bug的时候,我们把这个开关打开,来进行热更新,否则就处在关闭状态下。
下面我占下我的代码:
//请求是否进行个更新 private void heatRegeneration() { httpUtils=new HttpUtils();//Xutils进行请求网络 String urlPath="http://ftp.zhengjin99.com/hq/anfix/update.json";//请求接口,其实就是一个静态文件{"andfix":2,"andfix_name":"hao"} httpUtils.send(HttpRequest.HttpMethod.GET, urlPath, null, new RequestCallBack<String>() { @Override public void onSuccess(ResponseInfo<String> responseInfo) { String code=responseInfo.result; try { JSONObject json=new JSONObject(code); int andFixCode=json.getInt("andfix"); String andFixName=json.getString("andfix_name"); if(andFixCode==1){//去下载,这是总的开关 //热更新 String terPath= getSDPath()+"/trader/"+andFixName+".apatch"; File file=new File(terPath); //判断是否需要热更新,需要的话就去更新 if(!file.exists()){ Logger.i("andfixone","文件不存在去下载"); dowmLoadAndFixSo(terPath); }else{ Logger.i("andfixone","文件存在,不去下载"); } } } catch (JSONException e) { e.printStackTrace(); } } @Override public void onFailure(HttpException error, String msg) { } }); } //下载文件,存入SD卡 private void dowmLoadAndFixSo(final String terPath) { if(Environment.MEDIA_MOUNTED.equals( Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()){ String urlPath="http://ftp.zhengjin99.com/hq/anfix/a.apatch";//这是两个版本生成的apatch文件 httpUtils.download(urlPath, terPath, true, new RequestCallBack<File>() { @Override public void onFailure(HttpException arg0, String arg1) { } @Override public void onSuccess(ResponseInfo<File> arg0) { // 初始化patch管理类 mPatchManager = new PatchManager(getApplicationContext()); // 初始化patch版本 mPatchManager.init("1"); // 加载已经添加到PatchManager中的patch mPatchManager.loadPatch(); try { mPatchManager.addPatch(terPath);//加载修复的bug } catch (IOException e) { e.printStackTrace(); } mPatchManager.removeAllPatch(); } }); } } public String getSDPath(){ File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState() .equals(Environment.MEDIA_MOUNTED); //判断sd卡是否存在 if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory();//获取跟目录 } return sdDir.toString(); }
需要注意的是静态文件里的andfix_name每次热更新时要该变,就是名字要不一样,不然SD卡中的文件不会替换。
这个下载地址Github:https://github.com/alibaba/AndFix
这是使用命令:
命令 : apkpatch.bat -f new.apk -t old.apk -o output1 -k debug.keystore -p android -a androiddebugkey -e android
-f <new.apk> :新版本
-t <old.apk> : 旧版本
-o <output> : 输出目录
-k <keystore>: 打包所用的keystore
-p <password>: keystore的密码
-a <alias>: keystore 用户别名
-e <alias password>: keystore 用户别名密码
总之来说,项目中有用到,但测试了之后,只能对某些方法有效,还有就是,有的手机不兼容,坑太多,不建议使用。相关具体信息可以加我QQ598254259问我。