Nuwa热修复实现

既然前面的AndFix暂时还不可行,那只能投奔QQ团队的Nuwa了。按照开发思路,本应先讲讲Nuwa的优缺再讲讲其使用的,但基于对Nuwa的了解不够深厚,我们还是先看看其具体使用吧。虽然网上已经提供了很多使用解说,但此刻仅求站在低点角度帮到大家填下小坑。

添加Nuwa插件

1.编辑工程的根build.gradle文件

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
        classpath 'cn.jiajixin.nuwa:gradle:1.2.2'
    }
}

2.在app的build.gradle中添加依赖SDK

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'cn.jiajixin.nuwa:nuwa:1.0.0'
}

apply plugin: "cn.jiajixin.nuwa"

此时引用 apply plugin: “cn.jiajixin.nuwa” 将有可能报异常Error:Cannot get property ‘taskDependencies’ on null object,其解决方法是将Gradle Plugin的版本降低至1.2.3就可以了,当然Gradle Version也要相应的降低至2.8。

设置plugin版本


使用Nuwa

1.在自定义Application当中初始化

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    Nuwa.init(this);
    Nuwa.loadPatch(this,"/sdcard/patch.jar")
}

这里有个需要注意的地方是自定义Application必须是直接继承自Application的类,如若自定义类AClazz继承自Application,又自定义类BClazz继承自AClazz并在注册表声明为BClazz,那么就会出现以下异常。也就是我们的初始化操作必须放在直属继承Application的AClazz当中。

java.lang.NoClassDefFoundError: Failed resolution of: Lcn/jiajixin/nuwa/Hack;
                                                     at archmages.github.hotfixsamples.HFApplication.<init>(HFApplication.java:17)
                                                     at archmages.github.hotfixsamples.MyApplication.<init>(MyApplication.java:12)
                                                     at java.lang.reflect.Constructor.newInstance(Native Method)

Caused by: java.lang.ClassNotFoundException: Didn't find class "cn.jiajixin.nuwa.Hack" on path: DexPathList[[zip file "/data/app/archmages.github.hotfixsamples-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
                                                     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                                                     at archmages.github.hotfixsamples.HFApplication.<init>(HFApplication.java:17) 
                                                            ... more

2.运行并成功安装APK
运行过程中可能会中途报错Execution failed for task ‘app:nuwaClassBeforeDexDebug’并在控制台将会输出以下信息

运行时有误

为解决以上遇到的问题,我们需要在app底下的build.gradle中加入multiDexEnabled true

defaultConfig {
    applicationId "archmages.github.hotfixsamples"
    minSdkVersion 14
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
}

顺利运行并安装APK完成之后可以在app\bulid\outputs\目录下发现nuwa\debug\patch\目录。此时我们需要把该目录复制到本地任意位置下,譬如将该目录直接放置到D:\目录下,应该是D:\nuwa\debug\patch\。目录必须是酱紫,否则将无法生成.jar补丁文件。

nuwa目录

补丁文件.jar生成

1.移动hash.txt文件
在复制好nuwa目录后,若将当前apk视为存在bug的apk,这是我们要把nuwa\debug\目录下的hash.txt文件复制到本地目录D:\nuwa\debug\下。

2.生成补丁命令
这里小编建议是在执行命令前都应该先Clean以下项目(app\bulid\outputs\ 内容将重置)。之后执行命令只要在项目的根目录下直接执行就可以了(根目录下存在gradlew与gradlew.bat两个文件)。

  • Mac:gradlew clean nuwaDebugPatch -P NuwaDir=D:\nuwa
  • Windows:gradlew.bat clean nuwaDebugPatch -P NuwaDir=D:\nuwa

执行命令过程也未必是一帆丰顺,或许我们会遇到如下问题$ANDROID_HOME is not defined导致失败跳出命令。

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:nuwaDebugPatch'.
> $ANDROID_HOME is not defined

* Try:         
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED   

以上问题比较好解决,我们给‘ANDRIOD_HOME’设置下SDK的目录就OK了,命令如下。之后再次执行生成.jar补丁的命令就没什么问题了。如果有发现执行命令结果提示成功但是没有生成补丁文件的,请确保以上操作无误或已经正确修改了相关BUG内容

成功执行命令并在app\bulid\outputs\nuwa\debug目录下生成补丁文件patch.jar的亲,只要把其放置到初始化时指定的补丁获取位置下重启APP即可生效,当然这只是本地操作,最终还是得通过下载实现的。

set ANDROID_HOME=D:\个人SDK根目录

聊聊Nuwa情况

回到一开始说的,讲完整个引用过程后,就该讲讲Nuwa的其他琐事了。这里得先声明下只是个人见解噢,后面依然会根据使用情况继续更新本块内容[20160915]。

1. 手机兼容性问题
真机测试中发现HTC6.0.1与MEIZU5.1的手机均无法实现热修复功能且异常退出。5.0以上的机子部分不行就比较尴尬了,如果对兼容性没有太概要求的,还是先将targetSdkVersion值修改为22压压惊先吧。

2. 新增或修改内容无效
顺利引用后小编试过增删图片资源,class文件以及.xml文件,结果都能在补丁文件中达到操作效果。但奇怪的是,如果当当只是编辑已有.xml文件内容,却无法生成补丁文件,这是为何?这里得感谢我的同事wneng,因为这是他发现的问题,并且还从hash.txt文件当中分析为何没能生成补丁文件的缘故,发现其中指定需要被生成为补丁的内容是有限制的,所以才无法生成补丁文件以及修复效果。具体有兴趣的亲可以继续探索下。

3. 对比AndFix
可修复文件类型更广阔,AndFix只能对应class文件做修复工作;执行过程并不比AndFix复杂;兼容性处理相对上比AndFix要稳定得多;需要重启APP应用才能生效,AndFix则是当次生效;除此以外Nuwa本身也还有很多不完善的地方,可参考下面内容深入了解。

4. patch.jar影响之源远流长
由于生成的补丁文件具有针对性,所以向上发布的项目源码必须另做存储处理。使用Git的尽量拓展到hotFix分支上,或者在发布分支上做Tag标记,另外须留意各补丁的版本与加载控制,否则极有可能影响应用程序的后继研发。

这里写图片描述

5. 听说能支持 gradle1.5.0,
标识只是为了跟上2.0的Instance Run。所以必须立刻马上拿下demo尝试一番,结果发行运行成功后并没有在build下出现传说中的nuwa目录,然后只得乖乖的将gradle版本降会1.2.3。

更多参考

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值