前言
RootProcessor处理@HiltAndroidApp、@HiltAndroidTest和@InternalTestRoot三种注解,以及该注解关联的注解。生成一个@ComponentTreeDeps修饰的节点,该节点再由ComponentTreeDepsProcessor类处理。
同样的,以下源码的学习对照该demo去理解事半功倍,否则感觉说的非常无厘头。
RootProcessor
RootType
当前枚举有两种:
-
ROOT: 表示节点使用@HiltAndroidApp修饰;
-
TEST_ROOT:表示节点使用@HiltAndroidTest或@InternalTestRoot修饰;
TestInjectorGenerator
如果RootType是TEST_ROOT类型,那么使用当前类用于生成一个新类。
@HiltAndroidTest或@InternalTestRoot修饰的节点规则:
-
@HiltAndroidTest或@InternalTestRoot修饰的节点不允许使用@AndroidEntryPoint修饰;
-
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修饰的类。
属性如下:
-
aggregatingElement:@ProcessedRootSentinel注解修饰的节点;
-
rootElements:当前@ProcessedRootSentinel#roots中的值表示的类或接口;
将ProcessedRootSentinelMetadata对象转换成ProcessedRootSentinelIr,属性:
-
fqName:@ProcessedRootSentinel注解修饰的节点;
-
roots:当前@ProcessedRootSentinel#roots中的值表示的类或接口;
AggregatedRootMetadata
dagger.hilt.internal.aggregatedroot.codegen包下使用@AggregatedRoot修饰的节点生成的对象,属性如下:
-
TypeElement aggregatingElement:dagger.hilt.internal.aggregatedroot.codegen包下使用@AggregatedRoot修饰的节点;
-
TypeElement rootElement:@AggregatedRoot#root中的节点,
-
TypeElement originatingRootElement:@AggregatedRoot#originatingRoot中的节点,
-
TypeElement rootAnnotation:@AggregatedRoot#rootAnnotation中的节点,
-
boolean allowsSharingComponent:true。
当前AggregatedRootMetadata对象转换成AggregatedRootIr对象,属性如下:
-
val fqName: dagger.hilt.internal.aggregatedroot.codegen包下使用@AggregatedRoot修饰的节点;
-
val root: @AggregatedRoot#root中的节点;
-
val originatingRoot: @AggregatedRoot#originatingRoot中的节点;
-
val rootAnnotation: @AggregatedRoot#rootAnnotation中的节点;
-
val allowsSharingComponent: Boolean = true。
AggregatedRootIrValidator
校验:
-
@HiltAndroidApp在一个项目中只允许出现一次;
-
同一个项目中不允许同时出现@HiltAndroidTest或@InternalTestRoot 和 @HiltAndroidApp;
- 可以理解为@HiltAndroidApp应用于项目,@HiltAndroidTest或@InternalTestRoot应用于测试环境;
-
如果@AggregatedRoot#rootAnnotation中的注解是@HiltAndroidTest或@InternalTestRoot && @AggregatedRoot#root包含在@ProcessedRootSentinel#roots中(已经被处理过了) ,那么不允许再次处理该注解;;
-
@AggregatedRoot#rootAnnotation中的注解如果是@HiltAndroidApp && @HiltAndroidApp包含在@ProcessedRootSentinel#roots中(已经被处理过了),那么不允许再次在当前项目中处理 @HiltAndroidApp注解;
可自行查看代码,这里的逻辑非常的绕口,必须理解的是**@ProcessedRootSentinel#roots收集的是@AggregatedRoot#rootAnnotation中处理过的注解**。
DefineComponentClassesMetadata
dagger.hilt.processor.internal.definecomponent.codegen包下使用@DefineComponentClasses注解修饰的节点生成DefineComponentClassesMetadata对象。
该包下的@DefineComponentClasses注解修饰的节点是通过@DefineComponent修饰的节点生成得来的,一般使用hilt提供的@DefineComponent修饰的节点,前面已有介绍,自行去查看。
属性如下:
-
TypeElement aggregatingElement:@DefineComponentClasses注解修饰的节点;
-
TypeElement element:@DefineComponentClasses#component或@DefineComponentClasses#builder里面的节点;
- @DefineComponentClasses#component或@DefineComponentClasses#builder有且仅有一个有效;<