Android 热补丁动态修复总结 eclipse版

参考文章

2. https://mp.weixin.qq.com/s?__biz=MzI1MTA1MzM2Nw==&mid=400118620&idx=1&sn=b4fdd5055731290eef12ad0d17f39d4a&scene=1&srcid=1106Imu9ZgwybID13e7y2nEi#wechat_redirect  QQ空间团队APP热补丁
3. https://m.oschina.net/blog/308583 设备的分包技术

比较偏向于使用eclipse 来进行开发, 并且这里不讲原理(因为以上博客对原理已经讲的够好了), 只讲自己的实现过程.
1.生成替换出现bug类的jar文件
App中有如下几个类
BugClass  出现bug的类
package com.danale.main;

public class BugClass {
	public String bug(){
		return "bug class";
	}
}
BugLoad   应用了bug的类
package com.danale.main;

public class BugLoad {
	
	public String show(){
		return new BugClass().bug();
	}
}
那么我们需要将BugClass该类替换掉
重写写这个类, 其包名,类需要与原来的类保持一致
package com.danale.main;

public class BugClass {
	public String bug(){
		return "fix bug class";
	}
}
需要将该BugClass 转成jar, 并将该jar使用dx工具进行转化
bin>jar cvf patch.jar com/danale/main/*           //将class文件转为jar包
bin>dx --dex --output patch_dex.jar patch.jar     //将jar包进行dx转化
然后将patch_dex.jar, 放置到assets 文件夹下.( 当然该文件同样可以放置到网上,这里为了方便处理)
ps: dx 工具在..\sdk\build-tools\android-4.4W,文件夹中,可以配置其环境变量,便于使用


2.防止应该该bug类的类被打上 CLASS_ISPREVERIFIED标签
( 1 )也就是说需要防止BugLoad类被打上 CLASS_ISPREVERIFIED标签, 那么就需要让BugLoad类引用其他dex中的类,才能防止被打上标签. 所以需要定义一个
帮助类. 如 AntilazyLoad
package dodola.hackdex;
/**
 *	用于嵌入的类
 */
public class AntilazyLoad {

}
将该类同样进行1的操作
bin>jar cvf hack.jar dodola/hackdex/AntilazyLoad           //将class文件转为jar包
bin>dx --dex --output hackdex_dex.jar hack.jar             //将jar包进行dx转化
将 hackdex_dex.jar, 放置到assets文件夹下,(该jar需要在app发布的时候已经定义好了)

( 2 ) 需要将BugLoad中注入AntilazyLoad引用. 由于BugLoad 和 AntilazyLoad 不在同一个dex中, 所以在代码编写的时候是不可能引用到AntilazyLoad. 所以需要将AnilazyLoad 注入到BugLoad的class字节码文件中, 这里就需要使用到 javassist库了. 当我们不再更改BugLoad,那么BugLoad的字节码文件也就不会重新生成, 那么我们可以拿到该字节码文件将 AntilazyLoad注入到BugLoad字节码中,如下
package com.javassist;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
/**
 * 用来个类添嵌入别的dex的方法 
 */
public class JavassistTask {
	public static void main(String[] args) throws Exception {
		String path = "D:/git-work-montum/MainApp/bin/"; 
		ClassPool classes = ClassPool.getDefault();
		classes.appendClassPath(path + "classes");
		CtClass c = classes.get("com.danale.main.BugLoad");
		CtConstructor ctConstructor = c.getConstructors()[0];
		ctConstructor.insertAfter("System.out.println(dodola.hackdex.AntilazyLoad.class);");
		c.writeFile(path+"/output");
	}
}
然后将 classes文件下的BugLoad.class 替换为 bin/ output/... 目录下的BugLoad.class, 可以使用反编译工具查看BugLoad.class 是否被注入成功,如下
package com.danale.main;

import dodola.hackdex.AntilazyLoad;
import java.io.PrintStream;

public class BugLoad
{
  public BugLoad()
  {
    Object localObject = null; System.out.println(AntilazyLoad.class); }

  public String show() {
    return new BugClass().bug();
  }
}


3.导入HotFix资源文件实现热修复

( 1 ) 此时assets文件加下已经有两个jar了, hackdex_dex.jar 和 patch_dex.jar , 由于AntilazyLoad是被注入到BugLoad中的, 为了防止AntilazyLoad找不到class, 需要在app的application的onCreate 方法中将hackdex_dex.jar加载进来, 如下:

import java.io.File;

import dodola.hotfixlib.HotFix;

import android.app.Application;
import android.content.Context;
import android.util.Log;

public class MainApp extends Application {
    
    @Override
    public void onCreate() {
        super.onCreate();
         File dexPath = new File(getDir("dex", Context.MODE_PRIVATE), "hackdex_dex.jar");
        Utils.prepareDex(this.getApplicationContext(), dexPath, "hackdex_dex.jar");
        HotFix.patch(this, dexPath.getAbsolutePath(), "dodola.hackdex.AntilazyLoad");
        try {
            Class<?> loadClass = this.getClassLoader().loadClass("dodola.hackdex.AntilazyLoad");
            Log.i("MainApp", "SUCCESS : " + loadClass);
        } catch (ClassNotFoundException e) {
            Log.i("MainApp", "EXCEPTION : " + e.getMessage());
            e.printStackTrace();
        }
    }
}

ps: Utils工具类就是将jar文件拷贝到dexPath处


( 2 ) 前面的准备工作做完了之后,就剩下最后一步了, 将patch_dex.jar中的BugClass 加载进来从而替换掉出现问题的类,如下

//准备补丁,从assert里拷贝到dex里
		File dexPath = new File(getDir("dex", Context.MODE_PRIVATE), "patch_dex.jar");
		Utils.prepareDex(this.getApplicationContext(), dexPath, "patch_dex.jar");
		HotFix.patch(this, dexPath.getAbsolutePath(), "com.danale.main.*");

至此, android 热补丁完成了

源文件下载

http://download.csdn.net/detail/qq_24551315/9574232











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值