Android热修复(Hot Fix)案例全剖析(一)
2016-10-02 16:25
274 查看
说到热修复技术,我们不得不先谈一下什么是冷修复。
为了便于大家形象具体的理解热修复技术的流程,我给大家画一幅原理图。
MainActivity代码如下:
出错的NullTest计算工具类:
布局文件代码:
OK,项目源码开发到此为止,接下来,我们通过使用ant命令,对该项目进行多分包构建,这次我们一共构建了两个dex包,特地把出错的NullTest类放到classes2.dex中去,为的就是方便后面的热修复。
主包配置文件清单:
完成以上所有操作后,我们将构建出来的APK安装到手机上,然后测试,点击执行操作按钮,发现项目崩溃并闪退。
2.生成补丁dex文件
修改错误代码后,我们clean一下项目,在项目的bin目录中找到生成的新的NullTest.class文件,连同该文件的包目录一并拷贝出来(注意其他的类文件通通去掉),这里我拷贝到桌面上的castiel文件夹中,同时在该文件夹中新建一个castieloutput文件夹,用于稍后存放编译的dex文件。
然后在cmd命令行中,利用SDK的dx工具编译生成新的dex文件
成功后,我们将生成的dex文件反编译,可以看到新的修复补丁文件已经将0改为1
到这里本篇博客就结束了,下一篇博客我们要做的事情就是用我们 classes2.dex(修复好的包)去动态替换classes2.dex(有Bug的包),实现热修复操作。
Android热修复(Hot Fix)案例全剖析(二)
冷修复
当我们发现上线的应用APK存在Bug,我们通过发布新的应用APK,去替换旧的应用APK,以达到解决Bug的目的,但是这样做存在很大的缺点,需要用户二次下载APK,浪费用户流量,费时、费力、用户体验差。热修复
当我们发现上线的应用APK存在Bug,我们在用户使用过程中就把Bug修复了,优点是其过程中用户不需要把应用程序停止、卸载、重新安装、重启,大大改善了用户体验。热修复原理解析
通常作为一款应用,最容易出现Bug的地方,是java代码。我们知道Oracle的套路,java源文件是被编译成.class文件,用ClassLoader加载.class;而安卓使用Dalvik/ART虚拟机,由于版权问题,谷歌把.class编译成了dex文件,并通过ClassLoader加载dex。我们的热修复方案,其实就是基于我之前博客中讲到的Android dex多分包方案实现的。想学习了解Android Dex多分包技术的童鞋,请点击链接查看:彻底掌握Android多分包技术MultiDex-用Ant和Gradle分别构建(一)为了便于大家形象具体的理解热修复技术的流程,我给大家画一幅原理图。
待修复项目搭建
明白了热修复的流程以后,为了方便给大家演示热修复的流程,我们首先新建一个含有Bug的项目,该项目有一个页面,页面中包含两个按钮,一个按钮点击后会执行错误未修复的代码,另一个按钮点击后执行热修复操作。MainActivity代码如下:
public class MainActivity extends Activity { Button btnOpen, btnModify; NullTest nt = new NullTest(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnOpen = (Button) findViewById(R.id.btn_open); btnModify = (Button) findViewById(R.id.btn_modify); btnOpen.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { nt.printAbcLength(MainActivity.this);// 执行计算 } }); btnModify.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { castielFixMethod();// 调用热修复方法 } }); } }
出错的NullTest计算工具类:
public class NullTest { int a = 8; int b = 0;// 故意设置为0 public void printAbcLength(Context context) { // 很明用8除0,一定会导致java.lang.ArithmeticException: / by zero异常 Toast.makeText(context, "count result:" + (a/b), Toast.LENGTH_LONG).show(); } }
布局文件代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="猴子搬来的救兵 http://blog.csdn.net/mynameishuangshuai" /> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_margin="10dp" android:src="@drawable/old" /> <Button android:id="@+id/btn_open" android:layout_width="200dp" android:layout_height="40dp" android:layout_below="@+id/imageView1" android:layout_margin="10dp" android:text="执行操作" /> <Button android:id="@+id/btn_modify" android:layout_width="200dp" android:layout_height="40dp" android:layout_below="@+id/btn_open" android:layout_margin="10dp" android:text="修复Bug" /> </RelativeLayout>
OK,项目源码开发到此为止,接下来,我们通过使用ant命令,对该项目进行多分包构建,这次我们一共构建了两个dex包,特地把出错的NullTest类放到classes2.dex中去,为的就是方便后面的热修复。
<!-- 构建多分包dex文件 --> <target name="multi-dex" depends="compile" > <echo message="Generate multi-dex..." /> <exec executable="${tools.dx}" failonerror="true" > <arg value="--dex" /> <arg value="--multi-dex" /> <arg value="--set-max-idx-number=10000" /> <arg value="--main-dex-list" /> <!-- 主包包含class文件列表 --> <arg value="${main-dex-rule}" /> <arg value="--minimal-main-dex" /> <arg value="--output=${bin}" /> <arg value="${bin}" /> <!-- <arg value="${libs}" /> --> </exec> </target>
主包配置文件清单:
com/castiel/demo/MainActivity.class
完成以上所有操作后,我们将构建出来的APK安装到手机上,然后测试,点击执行操作按钮,发现项目崩溃并闪退。
开发热修复补丁dex文件
1.发现并修改Bugpublic class NullTest { int a = 8; int b = 1;// 这里我们将出错的0改为1 public void printAbcLength(Context context) { Toast.makeText(context, "count result:" + (a/b), Toast.LENGTH_LONG).show(); } }
2.生成补丁dex文件
修改错误代码后,我们clean一下项目,在项目的bin目录中找到生成的新的NullTest.class文件,连同该文件的包目录一并拷贝出来(注意其他的类文件通通去掉),这里我拷贝到桌面上的castiel文件夹中,同时在该文件夹中新建一个castieloutput文件夹,用于稍后存放编译的dex文件。
然后在cmd命令行中,利用SDK的dx工具编译生成新的dex文件
成功后,我们将生成的dex文件反编译,可以看到新的修复补丁文件已经将0改为1
到这里本篇博客就结束了,下一篇博客我们要做的事情就是用我们 classes2.dex(修复好的包)去动态替换classes2.dex(有Bug的包),实现热修复操作。
Android热修复(Hot Fix)案例全剖析(二)
相关文章推荐
- Android热修复(Hot Fix)案例全剖析(一)
- Android热修复(Hot Fix)案例全剖析(二)
- Android热修复(Hot Fix)案例全剖析(二)
- [Android 泥水匠] Android基础 之一:浅谈Android架构到HelloWorld案例的剖析
- Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!
- [MiniPro]Android GPS-从上到下整个框架剖析与案例解说
- Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!
- Android中热修复框架AndFix原理解析及案例使用
- Android anfix热修复 原理剖析
- [Android 泥水匠] Android基础 之一:浅谈Android架构到HelloWorld案例的剖析
- AIDL/IPC Android AIDL/IPC 进程通信机制——超具体解说及使用方法案例剖析(播放器)
- Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!
- Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!
- AIDL/IPC Android AIDL/IPC 进程通信机制——超详细讲解及用法案例剖析(播放器)
- AIDL/IPC Android AIDL/IPC 进程通信机制——超详细讲解及用法案例剖析(播放器)
- Android实例剖析笔记(三)
- 田志刚:知识管理六大失败案例剖析
- Anatomy of an Android Application - 剖析Android應用程式的四大區塊
- Android实例剖析笔记(二)
- Android实例剖析笔记(三)