码迷,mamicode.com
首页 > 其他好文 > 详细

Nuwa热修复实现

时间:2016-05-07 08:30:10      阅读:1540      评论:0      收藏:0      [点我收藏+]

标签:

既然前面的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。

技术分享


使用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补丁文件。

技术分享

补丁文件.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的其他琐事了。这里先声明只是小编本人的见解,只是聊聊,后面依然会根据使用情况继续更新本块内容。

情况1:部分手机无修复效果
具体是由于什么原因照成的小编也不是很清楚,只是在测试中发现HTC6.0.1与MEIZU5.1的手机存在该情况。最终的解决方案是将app下bulid.gardle当中的targetSdkVersion值修改为22就可以了,这得感谢我的组长kakash提出的想法哈哈。

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

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

其他情况:参考

Nuwa热修复实现

标签:

原文地址:http://blog.csdn.net/gzejia/article/details/51330663

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!