Android-->热修复,补丁实战

原创 2015年11月18日 16:27:38

阅读此文之前,可以先阅读: http://blog.csdn.net/lmj623565791/article/details/49883661

在此不阐述原理, 只描述实际过程.


1:首先新建一个Android Studio Android 工程(Project)
新建2个类:

public class BugWrapperClass {//存在Bug的类, 需要被一个父类包含
    public String getBug() {
        return new BugClass().getBug();
    }
}
public class BugClass {
    public String getBug(){
        return "Is In Bug Class";//用于修复的类
    }
}
  ((TextView) findViewById(R.id.text_view)).setText( new BugWrapperClass().getBug());//调用的方法, 很简单,不详述了.

2:这个时候,需要替换BugClass.class, 步骤如下:
需要修改项目 Module 的 build.gradle 如下:

apply plugin: 'com.android.application'

//注意此处
task('insertClass') << {
    String classPath = file('build/intermediates/classes/debug')//项目编译class所在目录
    dodola.patch.PatchClass.process(classPath, project(':InsertLib').buildDir
            .absolutePath + '/intermediates/classes/debug')//第二个参数是hackdex的class所在目录
}

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        ...
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    //注意此处
    applicationVariants.all { variant ->
        variant.dex.dependsOn << insertClass}
}

dependencies {
    ...
}

//以下方法在,buildSrc(Moudle中),后面有下载地址;主要最用就是去除 CLASS_ISPREVERIFIED 标识

public class PatchClass {
    /**
     * 植入代码
     * @param buildDir 是项目的build class目录,就是我们需要注入的class所在地
     * @param lib 这个是hackdex的目录,就是AntilazyLoad类的class文件所在地
     */
    public static void process(String buildDir, String lib) {

        println(lib)
        ClassPool classes = ClassPool.getDefault()
        classes.appendClassPath(buildDir)
        classes.appendClassPath(lib)

        println("buildDir:" + buildDir)
        println("lib:" + lib)

        CtClass c1 = classes.getCtClass("com.rsen.BugWrapperClass")//需要去除标识的类
        if (c1.isFrozen()) {
            c1.defrost()
        }
        println("====添加构造方法====")
        def constructor1 = c1.getConstructors()[0];
        constructor1.insertBefore("System.out.println(com.angcyo.insertlib.InsertClass.class);")
        c1.writeFile(buildDir)
    }
}

修改完 build.gradle之后,此时运行项目,调用代码时,会报错;
因为 InsertClass.class类,没有加载;
新建一个 lib moudle,新建一个 InsertClass.class类;如下:

public class InsertClass {
//这个类,声明了就可以
}

编译成jar, 再用dx工具,打包成dex类型的jar:
方法如下:

Make Moudle之后,会在
(Moudle根目录)\build\intermediates\bundles\debug\classes.jar 这个目录下生成jar文件

在 (Android SDK目录)\build-tools\23.0.2\dx.bat 这个目录有dx工具

通过 命令:dx  --dex --output hack_dex.jar hack.jar
可以得到 dex类型的jar

得到dex.jar文件之后,复制到项目assets目录中,通过以下代码,加载InsertClass类

public class RApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        File dexPath = new File(getDir("dex", Context.MODE_PRIVATE), "indertlib_dex.jar");
        HotFix.prepareDex(this.getApplicationContext(), dexPath, "indertlib_dex.jar");
        HotFix.patch(this, dexPath.getAbsolutePath(), "com.angcyo.insertlib.InsertClass");
        try {
            this.getClassLoader().loadClass("com.angcyo.insertlib.InsertClass");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
//注意要在manifest.xml文件中 使用这个application哦;
//这里需要依赖 HotFix 库moudle,后面有下载地址;

此时,项目可以正常运行了;

3:打补丁
新建一个 补丁 lib moudle;创建需要修补的类

public class BugClass {
    public String getBug(){
        return "Is Patch Rsen Class";//此方法已经修改了.
    }
}

通过之前介绍的方法: 使用dx工具,获取dex类型的jar;
将得到的jar,放在项目assets目录;

4:加载补丁

  //准备补丁,从assert里拷贝到dex里
  File dexPath = new File(getDir("dex", Context.MODE_PRIVATE), "patch_dex.jar");
  HotFix.prepareDex(this.getApplicationContext(), dexPath, "patch_dex.jar");
  HotFix.patch(this, dexPath.getAbsolutePath(), "com.rsen.BugClass");//包名要一致

  Snackbar.make(findViewById(R.id.text_view), "打补丁完成", Snackbar.LENGTH_LONG)
          .setAction("Action", null).show();
  //注意,在打补丁之前,先不要调用BugClass类,否则打补丁会失败;

热修复的方法有点复杂,如果有更容易实现的方法,欢迎告之,不胜感激;


文中依赖的2个库项目,和整个项目下载地址:https://github.com/angcyo/HotFixMultiDexDemo

特别提示:gradle的插件版本只能使用 1.3.0; 否则编译会出错!

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0' //注意此行
    }
}

至此: 文章就结束了,如有疑问: QQ群:274306954 欢迎您的加入.

版权声明:欢迎转载,转载请注明出处-->http://blog.csdn.net/angcyo

Android 热补丁技术的探索与简单实战----Qzone方案

Android app客户端与Web app相比的有一个劣势在于web app有更新不需要重新安装程序,而Android app如果有更新则需要重新下载最新版本安装完成更新,这个缺点无疑会给用户带来不...
  • u012760183
  • u012760183
  • 2016年07月28日 13:36
  • 1433

Android热修复之 - 打补丁原来如此简单

1.概述  今天我们来看一看纯java代码打补丁的方式会是怎样,纯Java代码是什么意思?因为上一期讲到阿里开源的热补丁里面涉及到NDK,会是会用但要自己去写NDK很多人估计不考谱,今天我们就用一种最...
  • z240336124
  • z240336124
  • 2017年02月16日 09:03
  • 1039

Tinker热修复,配置时的坑

微信热修复Tinker
  • l_and_h_555
  • l_and_h_555
  • 2017年01月05日 13:49
  • 846

Android热补丁动态修复技术(完结篇):自动生成打包带签名的补丁,重构项目

一、关于前面四篇博文 Android热补丁动态修复技术(一):从Dex分包原理到热补丁 Android热补丁动态修复技术(二):实战!CLASS_ISPREVERIFIED问题! Android热...
  • u010386612
  • u010386612
  • 2016年05月05日 12:41
  • 4317

热补丁方案和Instant-Run总结

热补丁方案和Instant-Run总结       Android的热补丁技术在今年一直很火爆,目前比较成熟的技术有淘宝的Dexposed、支付宝的Andfix、微信的Dexdiff和QZone的H...
  • u014761700
  • u014761700
  • 2016年08月16日 15:45
  • 1431

如何使用阿里百川hotfix热修复功能(三)

这章我们进行patch补丁操作,参考 :  如何使用阿里百川hotfix热修复功能(一) 如何使用阿里百川hotfix热修复功能(二)      1.下载打包工具 patch补丁包生成需要使用到打...
  • wsdbssxq
  • wsdbssxq
  • 2016年11月22日 16:58
  • 2754

如何使用阿里百川hotfix热修复功能(一)

最近热修复技术渐渐火起来,当 App 发布之后,如果出现客户端的问题,实在是干着急……有时候仅仅是为了修改了一行代码,也要付出巨大的成本进行换包和重新发布。所以引入了热修复这个技术,阿里百川的解释是...
  • wsdbssxq
  • wsdbssxq
  • 2016年11月22日 15:36
  • 2544

阿里云热修复技术Sophix的快速接入

1.首先去官网注册并登录账号,并进入控制台创建应用,获得相关的AppId,AppSecret,RSA密钥 2.然后按着接口文档,走流程配置相关信息就行,这个不细说,官网文档写的很清楚3.代码主要有两...
  • qq_33337504
  • qq_33337504
  • 2017年09月06日 11:27
  • 522

Android热补丁动态修复技术(四):自动化生成补丁——解决混淆问题

一、前言在上一章中,我们使用javassist成功为项目注入了System.out.println(AntilazyLoad.class);这行代码,解决了class_ispreverified问题,...
  • u010386612
  • u010386612
  • 2016年04月21日 18:01
  • 4405

Android 热修复方案Tinker(四) 资源补丁加载

想要做资源的更新首先需要了解分析资源加载流程,这样才能找到突破口.一般我们在应用中使用和加载资源都是通过Context对象的getResources方法.这里以Android 6.0的源码分析资源加载...
  • l2show
  • l2show
  • 2016年12月04日 16:37
  • 4899
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android-->热修复,补丁实战
举报原因:
原因补充:

(最多只允许输入30个字)