8.基于Dagger2.38.1的hilt源码-RootProcessor和ComponentTreeDepsProcessor

前言

RootProcessor处理@HiltAndroidApp、@HiltAndroidTest和@InternalTestRoot三种注解,以及该注解关联的注解。生成一个@ComponentTreeDeps修饰的节点,该节点再由ComponentTreeDepsProcessor类处理。

同样的,以下源码的学习对照该demo去理解事半功倍,否则感觉说的非常无厘头。

RootProcessor

RootType

当前枚举有两种:

  1. ROOT: 表示节点使用@HiltAndroidApp修饰;

  2. TEST_ROOT:表示节点使用@HiltAndroidTest或@InternalTestRoot修饰;

TestInjectorGenerator

如果RootType是TEST_ROOT类型,那么使用当前类用于生成一个新类。

@HiltAndroidTest或@InternalTestRoot修饰的节点规则:

  1. @HiltAndroidTest或@InternalTestRoot修饰的节点不允许使用@AndroidEntryPoint修饰;

  2. test测试节点一定使用了@HiltAndroidTest注解,是否使用@InternalTestRoot随意。

demo:

@HiltAndroidTest
public class TestApplication extends Application{...}

生成的类如下:

 @OriginatingElement(topLevelClass = TestApplication.class)
 @GeneratedEntryPoint
 @InstallIn(SingletonComponent.class)
 @Generated("TestInjectorGenerator")
 public interface TestApplication_GeneratedInjector {
   public void injectTest(TestApplication testApplication);
 }

AggregatedRootGenerator

@HiltAndroidApp或@HiltAndroidTest修饰的节点生成@AggregatedRoot修饰的类。

com.aregyan.github包下的demo:

@HiltAndroidApp
class Application : Application() {...}

生成类在dagger.hilt.internal.aggregatedroot.codegen包下:

/**
 * This class should only be referenced by generated code! This class aggregates information across multiple compilations.
 */
@AggregatedRoot(
    root = "com.aregyan.github.Application",
    originatingRoot = "com.aregyan.github.Application",
    rootAnnotation = HiltAndroidApp.class
)
public class _com_aregyan_github_Application {
}

ProcessedRootSentinelMetadata

dagger.hilt.internal.processedrootsentinel.codegen包下使用@ProcessedRootSentinel注解修饰的节点生成的对象。

@AggregatedRoot修饰的节点会再次在dagger.hilt.internal.processedrootsentinel.codegen包生成一个@ProcessedRootSentinel修饰的类。

属性如下:

  1. aggregatingElement:@ProcessedRootSentinel注解修饰的节点;

  2. rootElements:当前@ProcessedRootSentinel#roots中的值表示的类或接口;

将ProcessedRootSentinelMetadata对象转换成ProcessedRootSentinelIr,属性:

  1. fqName:@ProcessedRootSentinel注解修饰的节点;

  2. roots:当前@ProcessedRootSentinel#roots中的值表示的类或接口;

AggregatedRootMetadata

dagger.hilt.internal.aggregatedroot.codegen包下使用@AggregatedRoot修饰的节点生成的对象,属性如下:

  1. TypeElement aggregatingElement:dagger.hilt.internal.aggregatedroot.codegen包下使用@AggregatedRoot修饰的节点;

  2. TypeElement rootElement:@AggregatedRoot#root中的节点,

  3. TypeElement originatingRootElement:@AggregatedRoot#originatingRoot中的节点,

  4. TypeElement rootAnnotation:@AggregatedRoot#rootAnnotation中的节点,

  5. boolean allowsSharingComponent:true。

当前AggregatedRootMetadata对象转换成AggregatedRootIr对象,属性如下:

  1. val fqName: dagger.hilt.internal.aggregatedroot.codegen包下使用@AggregatedRoot修饰的节点;

  2. val root: @AggregatedRoot#root中的节点;

  3. val originatingRoot: @AggregatedRoot#originatingRoot中的节点;

  4. val rootAnnotation: @AggregatedRoot#rootAnnotation中的节点;

  5. val allowsSharingComponent: Boolean = true。

AggregatedRootIrValidator

校验:

  1. @HiltAndroidApp在一个项目中只允许出现一次;

  2. 同一个项目中不允许同时出现@HiltAndroidTest或@InternalTestRoot 和 @HiltAndroidApp;

  • 可以理解为@HiltAndroidApp应用于项目,@HiltAndroidTest或@InternalTestRoot应用于测试环境;
  1. 如果@AggregatedRoot#rootAnnotation中的注解是@HiltAndroidTest或@InternalTestRoot && @AggregatedRoot#root包含在@ProcessedRootSentinel#roots中(已经被处理过了) ,那么不允许再次处理该注解;;

  2. @AggregatedRoot#rootAnnotation中的注解如果是@HiltAndroidApp && @HiltAndroidApp包含在@ProcessedRootSentinel#roots中(已经被处理过了),那么不允许再次在当前项目中处理 @HiltAndroidApp注解;

可自行查看代码,这里的逻辑非常的绕口,必须理解的是**@ProcessedRootSentinel#roots收集的是@AggregatedRoot#rootAnnotation中处理过的注解**。

DefineComponentClassesMetadata

dagger.hilt.processor.internal.definecomponent.codegen包下使用@DefineComponentClasses注解修饰的节点生成DefineComponentClassesMetadata对象。

该包下的@DefineComponentClasses注解修饰的节点是通过@DefineComponent修饰的节点生成得来的,一般使用hilt提供的@DefineComponent修饰的节点,前面已有介绍,自行去查看。

属性如下:

  1. TypeElement aggregatingElement:@DefineComponentClasses注解修饰的节点;

  2. TypeElement element:@DefineComponentClasses#component或@DefineComponentClasses#builder里面的节点;

  • @DefineComponentClasses#component或@DefineComponentClasses#builder有且仅有一个有效;<
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值