AndFix 热补丁修复 操作方法
来源:互联网 发布:windows jdk环境变量 编辑:程序博客网 时间:2024/05/19 10:53
本文转自http://blog.csdn.net/lpftobetheone/article/details/50435371
搜索发现有这3种方式可以实现(至于其他的方式,暂不清楚)
1.dexposed github https://github.com/alibaba/dexposed
2.andfix github https://github.com/alibaba/AndFix
3.bsdiff http://blog.csdn.net/lazyer_dog/article/details/47173013
dexposed和andfix是alibaba的开源项目,都是apk增量更新的实现框架,目前dexposed的兼容性较差,只有2.3,4.0~4.4兼容,其他Android版本不兼容或未测试,详细可以去dexposed的github项目主页查看,而andfix则兼容2.3~6.0,所以就拿这个项目来实现增量更新吧。至于bsdiff,只是阅览了一下,还没研究过。首先 git clone github https://github.com/alibaba/AndFix,将andfix项目下载下来,Android studio可以在build.gradle里导入andfix,
compile 'com.alipay.euler:andfix:0.3.1'
但是我是使用module的方式添加andfix,这样可以直接查看编辑源码,而且直接gradle导入的话还有个问题,后面再说。andfix项目里有sample,导入也行,自己新建也行,我是自己新建项目,接着导入andfix作为module,demo里就两个类,mainactivity和myapplication
andfix里有些文件夹不用导入的,例如tools,doc等,记得新建jniLibs文件夹,libs里的so文件移到jniLibs里。
public class MainApplication extends Application { private static final String TAG = "euler"; private static final String APATCH_PATH = "/out.apatch"; private static final String DIR = "apatch";//补丁文件夹 /** * patch manager */ private PatchManager mPatchManager; @Override public void onCreate() { super.onCreate(); // initialize mPatchManager = new PatchManager(this); mPatchManager.init("1.0"); Log.d(TAG, "inited."); // load patch mPatchManager.loadPatch();// Log.d(TAG, "apatch loaded."); // add patch at runtime try { // .apatch file path String patchFileString = Environment.getExternalStorageDirectory() .getAbsolutePath() + APATCH_PATH; mPatchManager.addPatch(patchFileString); Log.d(TAG, "apatch:" + patchFileString + " added."); //这里我加了个方法,复制加载补丁成功后,删除sdcard的补丁,避免每次进入程序都重新加载一次 File f = new File(this.getFilesDir(), DIR + APATCH_PATH); if (f.exists()) { boolean result = new File(patchFileString).delete(); if (!result) Log.e(TAG, patchFileString + " delete fail"); } } catch (IOException e) { Log.e(TAG, "", e); } }
public class MainActivity extends Activity { private static final String TAG = "euler"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); toast(); } @Override protected void onDestroy() { super.onDestroy(); android.os.Process.killProcess(android.os.Process.myPid()); } //旧方法,1.apk
private void toast() { Toast.makeText(this, "old", Toast.LENGTH_SHORT).show(); }}
刚刚说的直接在gradle里导入andfix会有个问题,是在原来的项目中,加载一次补丁后,out.apatch文件会copy到getFilesDir目录下的/apatch文件夹中,在下次补丁更新时,会检测补丁是否已经添加在apatch文件夹下,已存在就不会复制加载sdcard的out.apatch。
原来的addpath方法
public void addPatch(String path) throws IOException { File src = new File(path); File dest = new File(mPatchDir, src.getName()); if(!src.exists()){ throw new FileNotFoundException(path); } if (dest.exists()) { Log.d(TAG, "patch [" + path + "] has be loaded."); return; } FileUtil.copyFile(src, dest);// copy to patch's directory Patch patch = addPatch(dest); if (patch != null) { loadPatch(patch); }}修改后,判断apatch下的out.apatch存在即删除掉,重新复制加载sdcard下的out.apatch
public void addPatch(String path) throws IOException { File src = new File(path); File dest = new File(mPatchDir, src.getName()); if (!src.exists()) { throw new FileNotFoundException(path); } if (dest.exists()) { Log.d(TAG, "patch [" + src.getName() + "] has be loaded."); boolean deleteResult = dest.delete(); if (deleteResult) Log.e(TAG, "patch [" + dest.getPath() + "] has be delete."); else { Log.e(TAG, "patch [" + dest.getPath() + "] delete error"); return; } } FileUtil.copyFile(src, dest);// copy to patch's directory Patch patch = addPatch(dest); if (patch != null) { loadPatch(patch); }}
还有源码混淆
-optimizationpasses 5 # 指定代码的压缩级别-dontusemixedcaseclassnames # 是否使用大小写混合-dontskipnonpubliclibraryclasses # 是否混淆第三方jar-dontpreverify # 混淆时是否做预校验-verbose # 混淆时是否记录日志-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法#重要,別忘了這些,不混淆andfix包,不混淆native方法-dontwarn android.annotation-dontwarn com.alipay.euler.**-keep class com.alipay.euler.** {*;}-keep class * extends java.lang.annotation.Annotation-keepclasseswithmembernames class * { native <methods>;}
接着打包1.apk,
然后修改mainactivity的toast(),打包2.apk
//修改Toast內容,2.apkprivate void toast() { Toast.makeText(this, "new", Toast.LENGTH_SHORT).show();}
cmd输入命令,具体参数看usage
apkpatch.bat -f new.apk -t old.apk -o output1 -k suning.keystore -p Suning1234 -a suning -e Suning1234 【完整命令】
如无错误,编译后会生成一个apatch文件,改名成out.apatch
安装打开1.apk
关闭app,将out.apatch放sdcard根目录后,重新打开app,toast方法改变了
ps:
1. 这里只是简单的测试了一下,没有复杂的功能,而且andfix不支持布局资源等的修改。
2. github主页的issues反应说Android4.0.4,以及5.0以上版本会crash,不过我使用了两个虚拟机,genymotion的4.2和5.0虚拟机,没有错误,其他请自测
3. 使用了apk加固时(360加固,百度加固等等),发现在加固前要先apkpatch制作补丁,不能使用加固后的apk制作,否则补丁无法使用,但是在加固前制作的补丁可以很容易的被反编译出源码
DEMO: http://download.csdn.net/detail/yaya_soft/9390182
- AndFix 热补丁修复 操作方法
- AndFix 热补丁修复
- AndFix 热补丁修复
- andfix 热补丁修复
- AndFix热补丁修复
- andfix 增量升级更新 热补丁修复
- andfix 增量升级更新 热补丁修复
- andfix 增量升级更新 热补丁修复
- andfix增量升级更新 热补丁修复
- Android AndFix热补丁动态修复框架使用教程
- Android AndFix热补丁动态修复框架使用教程
- (4.2.32.5)android热修复之Andfix方式:Andfix的补丁生成方法分析
- AndFix热修复实现
- AndFix热修复问题
- 阿里巴巴andfix热修复
- AndFix热修复笔记
- Android 热修复-AndFix
- AndFix热修复Demo
- CSS清除浮动_清除float浮动
- Eclipse+Git搭建小型团队开发环境(二)云端代码和本地代码冲突的处理方法
- BootStrap实用代码片段(持续总结)
- 运维监控信息收集
- POJ 1006
- AndFix 热补丁修复 操作方法
- Java 线程中的Join、wait、notify,sleep
- 程序员高薪
- codeforces_622C. Not Equal on a Segment
- Hexo添加RSS和评论插件
- 揭秘webdriver实现原理
- Servlet - Request、Session、servletContext区别
- 运用c语言做出简单的贪吃蛇程序
- Spring源码之ApplicationContext(二)准备工作