Android热修复相关

Android热修复相关

Robust 字节码插桩 代理 自动埋点
Tinker dex差分(bsdiff差分不关心文件格式 二进制全格式) 反射 类加载
Qzone dex差分 反射 类加载
  1. java中的类加载 双亲委托

    protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
        {
                // First, check if the class has already been loaded
                Class c = findLoadedClass(name);//判断类是否已经加载过
                if (c == null) {
                    long t0 = System.nanoTime();
                    try {
                        if (parent != null) {
                            c = parent.loadClass(name, false);//父类加载器优先加载
                        } else {
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {
                        // ClassNotFoundException thrown if class not found
                        // from the non-null parent class loader
                    }
    
                    if (c == null) {
                        // If still not found, then invoke findClass in order
                        // to find the class.
                        long t1 = System.nanoTime();
                        c = findClass(name);//调用当前类加载器的findClass方法进行加载
    
                        // this is the defining class loader; record the stats
                    }
                }
                return c;
        }
    
  2. android中的类加载器

    • BootClassLoader 系统类
    • PathClassLoader
    • DexClassLoader

PathClassLoader中反射获取makePathElements()方法 得到补丁包Element[]

将新补丁包与原包合并 通过System.arraycopy(...)

CLASS_ISPREVERIFIED 标记错误 导致修复异常

使用javaessit进行字节码插桩 让原来的所有class都引用补丁的类

img
gradle插桩
类比为 用 gson,fastjson这类第三方框架来修改json文件。我们也可以利用 特定的手段来自由修改class文件。这类技术框架有ASM,AspectJ, Javassist等。 由于我们androidStudio用gradle来构建项目,所以,还需要我们自定义gradle插件,来在合适的时机 使用ASM 这种技术框架来在class文件中修改字节码内容。
javac命令之后,dx命令之前
gradle执行项目构建,是通过一个一个的task来进行。比如 将java文件用javac命令编译为 class,任务名字叫做::app:compileDebugJavaWithJavac
img
  gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
        @Override
        void beforeEvaluate(Project project) {
            println " add project evaluation lister beforeEvaluate,project path is: "+project
        }

        @Override
        void afterEvaluate(Project project, ProjectState state) {
            println " add project evaluation lister afterProject,project path is:"+project
        }
    }

在afterEvaluate解析完成之后执行

anroid.getApplicationVariants().all{
    variant -> 
        String variantName = variant.getName(); //debug 或者 release
        String capitializeName = variantName.capitalize();//首字母大写
        Task dexTask = project.getTasks().findByName("transformClassWithDexBuilderFor" + capitializeName);
        dexTask.doFrist{....打包任务之前进行插桩}
}

ASM进行插桩

ClassReader cr = new ClassReader(inputStream);
ClassWriter cw = new ClassWriter(cr,0);
ClassVisitor cv = new ClassVisitor(Opcodes.ASM5,cw){
     public MethodVisitor visitMethod( final int access,final String name,final String desc,final String signature, final String[] exceptions) {
         MethodVisitor mv = super.visiMethod(access,name,desc,signature,exceptions);
         mv = new MethodVisitor(Opcodes.ASM4,mv){
             visitlnsn(int opcode){
                 //在构造方法中插入类的引用
                 if("<init>".equals(name)&&opcode==Opcodes.RETURN){
                     .....
                 }
                 super.visitlnsn(opcode);
             }
         }
         return mv;
     }
}
cr.accept(cv,0);//启动分析

Android N 混合编译

AOT提前编译 导致类被加载无法被替换

解决方式 使用运行时替换PathClassloader

Thread.currentThread().setContextClassloader(classLoader);

LoaderApk+Resources+DrawableInflater(参考Tinker)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容