关于热更新的学习记录

关于AndFix的实现原理。

1. 创建无bug的dex。

2. 放入到工程中。

3. 通过java代码把dex存放到安装目录的文件夹下。

4. 加载dex。

5. 通过jni层进行方法替换。

java层关键代码:

DexFile dexFile1 = DexFile.loadDex(dexFile.getAbsolutePath(),okDexFile.getAbsolutePath(),Context.MODE_PRIVATE);// load dex

	    Enumeration<String> entries = dexFile1.entries();// 对load的类进行遍历。

            while ( entries.hasMoreElements()){// 遍历类
                String key = entries.nextElement();
               
                Class<?> okClass = dexFile1.loadClass(key,getClass().getClassLoader());// 获取类

                if(okClass ==null ){
                    continue;
                }
                
                findBugMethod(okClass);
            }
private void findBugMethod(Class<?> okClass){
        // 获取该类中的所有方法。
        Method[] methods = okClass.getDeclaredMethods();
        for(Method method:methods){
            // 获取注解。已经指明注解类型。
            MethodReplace methodReplace = method.getAnnotation(MethodReplace.class);
            if(methodReplace == null){
                continue;
            }

            // 将要修复的错误类和错误方法
            String bugClassName = methodReplace.className();
            String bugMethodName = methodReplace.methodName();

            // 获取Bug Method 实例.也就是该方法的标识。不一定是实例参数.
            // 该方法在内存卡的映射地址
            try {
                Method bugMethod = Class.forName(bugClassName).getDeclaredMethod(bugMethodName,method.getParameterTypes());
                if(bugMethod != null){
                    replaceArt(bugMethod,method);
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

    }

C层实现。进行方法替换。

    ArtMethod* smeth = (ArtMethod*)env->FromReflectedMethod(jobject2);
    ArtMethod* dmeth = (ArtMethod*)env->FromReflectedMethod(jobject3);

    smeth->declaring_class_=dmeth->declaring_class_;
    smeth->dex_cache_resolved_types_=dmeth->dex_cache_resolved_types_;
    smeth->access_flags_=dmeth->access_flags_;
    smeth->dex_cache_resolved_methods_=dmeth->dex_cache_resolved_methods_;

    smeth->dex_code_item_offset_=dmeth->dex_code_item_offset_;
    smeth->method_index_=dmeth->method_index_;
    smeth->dex_method_index_=dmeth->dex_method_index_;

    smeth->ptr_sized_fields_.entry_point_from_interpreter_=dmeth->ptr_sized_fields_.entry_point_from_interpreter_;
    smeth->ptr_sized_fields_.entry_point_from_jni_=dmeth->ptr_sized_fields_.entry_point_from_jni_;
    smeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_=dmeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_;

注意点:

1. 需要错误类已经有实例。也就是已经实例化。静态的未尝试。







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值