art/runtime/native/java_lang_reflect_Method.cc

static jobject Method_invoke(JNIEnv* env, jobject javaMethod, jobject javaReceiver,
                             jobject javaArgs) {
  ScopedFastNativeObjectAccess soa(env);
  return InvokeMethod(soa, javaMethod, javaReceiver, javaArgs);

Method_invoke函数中又调用了InvokeMethod函数:
art/runtime/reflection.cc

jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaMethod,
                     jobject javaReceiver, jobject javaArgs, size_t num_frames) {

...
  ObjPtr<mirror::Executable> executable = soa.Decode<mirror::Executable>(javaMethod);
  const bool accessible = executable->IsAccessible();
  ArtMethod* m = executable->GetArtMethod();//1
...
}

注释1处获取传入的javaMethod(Key的show方法)在ART虚拟机中对应的一个ArtMethod指针,ArtMethod结构体中包含了Java方法的所有信息,包括执行入口、访问权限、所属类和代码执行地址等等,ArtMethod结构如下所示。
art/runtime/art_method.h

class ArtMethod FINAL {
...
 protected:
  GcRoot<mirror::Class> declaring_class_;
  std::atomic<std::uint32_t> access_flags_;
  uint32_t dex_code_item_offset_;
  uint32_t dex_method_index_;
  uint16_t method_index_;
  uint16_t hotness_count_;
 struct PtrSizedFields {
    ArtMethod** dex_cache_resolved_methods_;//1
    void* data_;
    void* entry_point_from_quick_compiled_code_;//2
  } ptr_sized_fields_;
}

ArtMethod结构中比较重要的字段是注释1处的dex_cache_resolved_methods_和注释2处的entry_point_from_quick_compiledcode,它们是方法的执行入口,当我们调用某一个方法时(比如Key的show方法),就会取得show方法的执行入口,通过执行入口就可以跳过去执行show方法。
替换ArtMethod结构体中的字段或者替换整个ArtMethod结构体,这就是底层替换方案。
AndFix采用的是替换ArtMethod结构体中的字段,这样会有兼容问题,因为厂商可能会修改ArtMethod结构体,导致方法替换失败。Sophix采用的是替换整个ArtMethod结构体,这样不会存在兼容问题。
底层替换方案直接替换了方法,可以立即生效不需要重启。采用底层替换方案主要是阿里系为主,包括AndFix、Dexposed、阿里百川、Sophix。

3.3 Instant Run方案

除了资源修复,代码修复同样也可以借鉴Instant Run的原理, 可以说Instant Run的出现推动了热修复框架的发展。
Instant Run在第一次构建apk时,使用ASM在每一个方法中注入了类似如下的代码:

IncrementalChange localIncrementalChange = $change;//1
        if (localIncrementalChange != null) {//2
            localIncrementalChange.access$dispatch(
                    "onCreate.(Landroid/os/Bundle;)V", new Object[] { this,
                            paramBundle });
            return;
        }

其中注释1处是一个成员变量localIncrementalChange ,它的值为$change,$change实现了IncrementalChange这个抽象接口。当我们点击InstantRun时,如果方法没有变化则$change为null,就调用return,不做任何处理。如果方法有变化,就生成替换类,这里我们假设MainActivity的onCreate方法做了修改,就会生成替换类MainActivity$override,这个类实现了IncrementalChange接口,同时也会生成一个AppPatchesLoaderImpl类,这个类的getPatchedClasses方法会返回被修改的类的列表(里面包含了MainActivity),根据列表会将MainActivity的$change设置为MainActivity$override,因此满足了注释2的条件,会执行MainActivity$override的access$dispatch方法,accessdispatch方法中会根据参数"onCreate.(Landroid/os/Bundle;)V"执行‘MainActivitydispatch方法中会根据参数"onCreate.(Landroid/os/Bundle;)V"执行MainActivitydispatch方法中会根据参数"onCreate.(Landroid/os/Bundle;)V"执行‘MainActivityoverride的onCreate方法,从而实现了onCreate方法的修改。
借鉴Instant Run的原理的热修复框架有Robust和Aceso。

尾声

我是2008年开始从事Android开发,途中也经历过各种,身边一起的同事,朋友走走留留,转前端的开饭店的,各种都有,但是都没有坚持,其实有些人能成功,必定有他的道理。人这一辈子,选好一件事,做好一件事,把这件事坚持做下去,精下去,你就比世界上大部分的人都要强了。所以看到这里的人,希望你们跟我一样坚持下去,因为我们不是看到希望才去努力,而且努力了才能看到光明啊!好了,本文到此结束。很感谢你的耐心看完!

需要下面资料的朋友 直接点击链接就可以领取了!

[Android学习PDF+架构视频+面试文档+源码笔记](

)
Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

  • 330页PDF Android学习核心笔记(内含8大板块)

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

  • Android学习的系统对应视频

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

  • Android进阶的系统对应学习资料

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

总结

我最近从朋友那里收集到了2020-2021BAT 面试真题解析,内容很多也很系统,包含了很多内容:Android 基础、Java 基础、Android 源码相关分析、常见的一些原理性问题等等,可以很好地帮助大家深刻理解Android相关知识点的原理以及面试相关知识

这份资料把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节;还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

这里也分享给广大面试同胞们,希望每位程序猿们都能面试成功~

CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》

Android 基础知识点

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

Java 基础知识点

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

Android 源码相关分析

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

常见的一些原理性问题

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2020面试真题解析

Android热修复原理热修复框架对比和代码修复,成功定级腾讯T3-2