2.Dagger2.38.1源码解析-ComponentProcessor注解规则

本文深入解析Dagger2的ComponentProcessor中的注解规则,涵盖component、componentMethod、creator、module及bindingMethod等多个方面,详细阐述了各规则的校验逻辑,帮助理解Dagger2的组件构建过程。

前言

github相关源码上有详细的注解,请自行对照github源码

简单解说下ProcessorComponent接口上module节点的作用:

  1. InjectBindingRegistryModule:对ComponentProcessor类中injectBindingRegistry变量最终实例化成InjectBindingRegistryImpl对象;

  2. SourceFileGeneratorsModule:为后面的代码生成提供实例化对象;

  3. ProcessingStepsModule:本章核心内容,对不同注解的逻辑处理;

  4. ProcessingEnvironmentModule:为提供XProcessingEnv可提供的参数:

  • 例如DaggerElements的实例化需要XConverters.toJavac(xProcessingEnv).getElementUtils()XConverters.toJavac(xProcessingEnv).getTypeUtils()作为参数;
  1. ComponentGeneratorModule:对component节点代码生成做单独处理;

  2. BindingMethodValidatorsModule:收集bindingMethod绑定方法校验;

  3. BindingGraphValidationModule: 绑定图形的校验;

以上主要目的都是为实例化提供需要的参数

直接看ProcessingStepsModule接口中的processingSteps方法,该方法的参数表示针对不同注解的处理:规则校验,生成对象,校验对象,最终生成代码等操作。

注解规则

component节点规则

该节点校验在ComponentProcessingStep类的isComponentValid方法中,如果节点使用了Component、ProductionComponent、Subcomponent、ProductionSubcomponent注解修饰使用此规则校验。

在ComponentValidator类中validate方法作为校验入口,校验规则如下:

  1. component节点上的componentAnnotation注解有且仅有一个;

  2. 如果component节点上使用了@CancellationPolicy注解修饰,那么当前component节点只能使用@ProductionSubcomponent或@ProductionComponent注解;

  3. component节点只能是abstract抽象类或接口;

  4. component节点最多只能存在一个creator节点,自行查看下面的creator的校验;

  5. component节点不能使用@Reusable修饰;

  6. 如果component是一个kotlin文件,那么componentMethod方法名不能使用java关键字,自行查看下面componentMethod方法校验;

  7. component节点中的入口(方法是abstract修饰或接口方法 && 方法无参 && 方法返回类型不是void && 方法没有使用泛型)并且该方法没有被重写,那么这个方法最多只能有一个;

  • 本条根据代码翻译过来的,因为这个校验使用了EntryPoints,所以叫入口方法,但是个人理解下(1)这个绝对不是入口方法(ProcessorComponent接口中void inject(ComponentProcessor processor)是货真价实的入口方法);(2)入口方法根据后面意思的理解也不是只存在一个;

  • 顺便理解下入口方法,入口方法是非private、非static修饰的abstract方法或接口方法,并且该方法的参数表示需要通过当前component节点进行实例化注入;

  1. componentMethod方法返回类型是subcomponent或subcomponent.creator,该方法最多只能出现一个;

  2. componentAnnotation#dependencies里面的类不能是module节点;

  3. componentAnnotation#modules校验,自行查看;

  4. 还需要对当前componentMethod方法返回类型是subcomponent(或subcomponent.creator)的subcomponent节点进行校验,从步骤1开始。

componentMethod节点校验规则

这里仅仅针对abstract修饰(或接口方法)、非private、非static的(包括从父级类继承过来的)componentMethod方法做校验,规则如下:

  1. componentMethod方法不能使用泛型,如果当前component节点是kotlin文件,那么注意componentMethod不能使用java关键字;

  2. 如果componentMethod方法的returnType返回类型是subcomponent节点,校验:

  • (1)当前componentMethod方法的参数必须是module节点,并且该方法只允许一次同一类型的module节点,并且这个module节点来源于(2)-subcomponent关联的module节点;

  • (2)收集subcomponent关联的module节点:①subcomponentAnnotation#modules里面的module节点;②条件①module节点上的注解moduleAnnotation#includes里面的module节点;③条件①和条件②的module节点的父级module(使用了moduleAnnotation注解)节点;

  1. componentMethod方法返回类型是subcomponent.creator节点,当前方法参数必须为空,并且对creator节点校验,自行查看;

  2. 方法返回类型不是subcomponent节点也不是subcomponent.creator节点,那么参数最多只允许有一个,

<think>根据您的问题,您想知道在Android Studio 2024.3.1版本中,如何正确添加Hilt和ButterKnife的Gradle插件依赖。这两个插件依赖需要添加到项目根目录下的`build.gradle`(有时也叫做`build.gradle.kts`,如果是Kotlin脚本)文件中。 注意:在较新的Android Studio版本中,项目结构可能有两种构建脚本: 1. 项目根目录的`build.gradle`(或`build.gradle.kts`) - 用于配置整个项目的构建脚本和插件依赖。 2. 每个模块(如app模块)的`build.gradle`(或`build.gradle.kts`) - 用于配置特定模块的构建。 您提到的两个插件依赖: - `classpath 'com.google.dagger:hilt-android-gradle-plugin:2.41'` 是Hilt的Gradle插件。 - `classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.1'` 是ButterKnife的Gradle插件。 这些插件依赖应该添加到项目根目录的`build.gradle`文件中的`buildscript.dependencies`块内。 以下是具体的步骤和代码: ### 步骤1:打开项目根目录的build.gradle文件 通常,项目根目录的`build.gradle`文件位于项目的顶层目录,与`settings.gradle`文件同级。 ### 步骤2:在buildscript块中添加依赖 在`buildscript`块中,确保有`repositories`(如google()和mavenCentral())和`dependencies`块。然后在`dependencies`块中添加这两个插件的classpath。 ### 示例代码(Groovy DSL - 即使用.gradle文件) ```groovy // 项目根目录的build.gradle文件 buildscript { repositories { google() mavenCentral() // 如果有其他仓库也可以添加 } dependencies { // 其他classpath,例如Android Gradle插件 classpath 'com.android.tools.build:gradle:8.3.2' // 请使用与您项目匹配的版本 // 添加Hilt插件 classpath 'com.google.dagger:hilt-android-gradle-plugin:2.41' // 添加ButterKnife插件 classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.1' // 注意:如果您使用Kotlin,还应该添加Kotlin插件 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22" // 请使用与您项目匹配的Kotlin版本 } } // 所有模块的配置,通常放在allprojects块中 allprojects { repositories { google() mavenCentral() } } ``` ### 注意事项: 1. **版本兼容性**:请确保您使用的插件版本与您的项目其他依赖(如Android Gradle插件版本、Kotlin版本)兼容。特别是Hilt版本2.41可能不是最新,建议查看官方文档获取最新版本。 2. **ButterKnife的使用**:请注意,ButterKnife已经不再维护,官方推荐使用ViewBinding或DataBinding。如果您的项目是新项目,建议不要使用ButterKnife。 3. **应用插件**:在模块的`build.gradle`中,您还需要应用这些插件。例如,在app模块的`build.gradle`中,您需要添加: ```groovy // 对于Hilt plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'kotlin-kapt' id 'dagger.hilt.android.plugin' // 应用Hilt插件 } ``` 对于ButterKnife,如果您仍要使用,在模块的`build.gradle`中应用: ```groovy apply plugin: 'com.jakewharton.butterknife' ``` 或者使用plugins块(注意ButterKnife插件可能不支持新的plugins DSL,所以可能需要使用apply方式)。 4. **同步项目**:添加依赖后,同步项目(Sync Project with Gradle Files)。 ### 如果使用Kotlin DSL(build.gradle.kts) 如果您的项目使用Kotlin DSL(即`build.gradle.kts`文件),则添加方式如下: ```kotlin // 项目根目录的build.gradle.kts buildscript { repositories { google() mavenCentral() } dependencies { classpath("com.android.tools.build:gradle:8.3.2") // Android Gradle插件 classpath("com.google.dagger:hilt-android-gradle-plugin:2.41") // Hilt classpath("com.jakewharton:butterknife-gradle-plugin:10.2.1") // ButterKnife classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22") // Kotlin插件 } } allprojects { repositories { google() mavenCentral() } } ``` ### 最后 请根据您的项目实际情况调整版本号,特别是Android Gradle插件版本和Kotlin版本。您可以在[Android Gradle插件版本说明](https://developer.android.com/studio/releases/gradle-plugin)中查看推荐版本。 §§相关问题§§: 1. 如何在模块的build.gradle中应用Hilt和ButterKnife插件? 2. ButterKnife和ViewBinding有什么区别?为什么ButterKnife不再推荐使用? 3. Hilt依赖注入框架中,如何定义和注入一个依赖? 4. 如何解决Gradle同步时出现的插件版本冲突问题?</think>### 在 Android Studio 2024.3.1 中配置 Hilt 和 ButterKnife 在 Android Studio 2024.3.1 (Giraffe) 中,您需要将插件依赖添加到项目根目录的 `build.gradle` 文件中。以下是具体步骤: #### 1. 打开项目根目录的 `build.gradle` 文件 路径:`YourProject/build.gradle`(不是 app 模块的 build.gradle) #### 2. 添加依赖到 `buildscript.dependencies` 块 ```groovy // 项目根目录的 build.gradle buildscript { repositories { google() mavenCentral() } dependencies { // Android Gradle 插件(必须与你的 AS 版本兼容) classpath 'com.android.tools.build:gradle:8.3.2' // 2024.3.1 推荐版本 // Hilt 插件 classpath 'com.google.dagger:hilt-android-gradle-plugin:2.48' // 建议使用最新版 // ButterKnife 插件 classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.1' // 如果你使用 Kotlin classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22" // 使用与项目兼容的版本 } } allprojects { repositories { google() mavenCentral() } } ``` #### 3. 在 app 模块中应用插件 在 app 模块的 `build.gradle` 中: ```groovy // app/build.gradle plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' // 如果使用 Kotlin id 'kotlin-kapt' // Kotlin 注解处理 id 'dagger.hilt.android.plugin' // Hilt 插件 } apply plugin: 'com.jakewharton.butterknife' // ButterKnife 插件 dependencies { // Hilt 依赖 implementation 'com.google.dagger:hilt-android:2.48' kapt 'com.google.dagger:hilt-android-compiler:2.48' // ButterKnife 依赖 implementation 'com.jakewharton:butterknife:10.2.1' annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' } ``` ### 版本兼容性说明 | 组件 | 推荐版本 | 说明 | |------|----------|------| | Android Gradle Plugin | 8.3.2 | 与 AS 2024.3.1 完全兼容 | | Hilt | 2.48 | 最新稳定版 | | ButterKnife | 10.2.1 | 最终维护版本 | | Kotlin | 1.9.22 | AS 2024.3.1 内置版本 | ### 重要注意事项 1. **同步 Gradle**:修改后点击 "Sync Now" 2. **JDK 要求**:确保使用 JDK 17(File > Project Structure > SDK Location) 3. **ButterKnife 替代**:考虑迁移到 View Binding 或 Jetpack Compose ```gradle // 替代 ButterKnife 的 View Binding android { buildFeatures { viewBinding true } } ``` 4. **Hilt 应用类**:确保 Application 类使用 `@HiltAndroidApp` ```java @HiltAndroidApp public class MyApplication extends Application { // ... } ``` ### 常见问题解决 如果遇到 "Plugin [id: 'dagger.hilt.android.plugin'] was not found": 1. 检查根 build.gradle 中的仓库配置(必须有 google() 和 mavenCentral()) 2. 确保网络可以访问 Maven 仓库 3. 尝试清理缓存:File > Invalidate Caches / Restart
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值