学习Hilt注解

注解是元数据,用于为代码(类、方法、字段等)添加标记信息,本身不直接影响程序行为。要学习如何使用别人定义的 Java 注解,通常要了解注解的作用目标、生命周期和元数据的处理细节。

1. 学习 Java 注解

1.1. 作用目标

@Target 决定了注解的作用目标,可以是下列之一或组合:

说明
ElementType.TYPE 类、接口、枚举、注解
ElementType.FIELD 字段(包括枚举常量
ElementType.METHOD 方法
ElementType.PARAMETER 方法参数
ElementType.CONSTRUCTOR 构造函数
ElementType.LOCAL_VARIABLE 局部变量
ElementType.ANNOTATION_TYPE 其他注解
ElementType.PACKAGE 包声明
ElementType.TYPE_PARAMETER 泛型类型参数
ElementType.TYPE_USE 任何类型
[表1 注解作用目标]

1.2. 生命周期

@Retention 决定了注解在程序的哪个生命周期阶段可以获取和使用。

说明
RetentionPolicy.SOURCE 仅保留在源码中,编译后丢弃
RetentionPolicy.CLASS 保留到编译后的字节码文件(.class),但运行时 JVM 不加载
RetentionPolicy.RUNTIME 保留到运行时,可通过反射获取

1.3. 元数据的处理者、处理时机和处理方式,以及如何影响程序行为

谁在什么时候,以什么方式处理这些元数据?结果对程序行为有什么样的改变?

@Nonnull 、 @Override 等注解常用于编译期代码检查。Lombok等注解在类加载期生成字节码。依赖注入注解通常由插件在编译期处理,生成注入代码;或者由框架在运行期框架初始化时,由框架注入对象。序列化/反序列化注解则是在运行期由序列化驱动类读取,来调整序列化/反序列化行为。

2. Hilt 注解

Hilt 注解可以分为4类:

|------------|----------------------------|
| 哪里需要注入对象 | @AndroidEntryPoint @Inject |
| 对象从哪里来 | @Provides @Binds @Module |
| 对象作用域和生命周期 | @Singleton @ActivityScoped |
| 组织和管理对象 | @HiltAndroidApp @InstallIn |

常用 Hilt 注解有

注解 目标 处理时机 说明
@HiltAndroidApp Application类 编译期 标记应用入口,触发 Hilt 代码生成。
@AndroidEntryPoint Activity类 编译期 标记 Hilt 容器,容器可以注入对象。
@Module 编译期 标记 Hilt 模块,模块负责创建对象。
@InstallIn 编译期 这个模块可以安装到哪些容器。
@Privodes 方法 编译期 这个方法可以创建注入对象。
@Binds @Module类的抽象方法 编译期 这个方法需要绑定到实现类。
@Inject 构造方法、域 编译期 这里需要注入对象。
@Singleton 类、方法 编译期 这是单例。
@ActivityScoped 类、方法 编译期 在Activity生命周期内是单例。
@FragmentScoped 类、方法 编译期 在Fragment生命周期内是单例。
@ViewModelScoped 类、方法 编译期 在ViewModel生命周期内是单例。
@ServiceScoped 类、方法 编译期 在Service生命周期内是单例。
@EntryPoint 接口 编译期 可以在非 Hilt 托管类中访问 Hilt 对象。
@HiltViewModel ViewModel类 编译期 这个 ViewModel 类可以使用 Hilt 注入对象。

2.1. Hilt 注解示例

复制代码
@HiltAndroidApp
public class MyApplication extends Application { ... }
复制代码
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity { ... }
复制代码
@Module
@InstallIn(SingletonComponent.class) // 指定模块安装在哪个组件中
public class AppModule { ... }
复制代码
@Module
@InstallIn(SingletonComponent.class)
public class NetworkModule {
    @Provides
    @Singleton // 作用域注解,表示单例
    public OkHttpClient provideOkHttpClient() {
        return new OkHttpClient.Builder().build();
    }
}
复制代码
@Module
@InstallIn(ActivityComponent.class)
public abstract class AnalyticsModule {
    @Binds
    public abstract AnalyticsService bindAnalyticsService(AnalyticsServiceImpl impl);
}
复制代码
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
    @Inject // Hilt 将注入一个 UserRepository 实例
    UserRepository userRepository;
    ...
}
复制代码
@ActivityScoped // 该 Repository 实例在同一个 Activity 内是单例
public class MainActivityRepository {
    @Inject
    public MainActivityRepository() { ... }
}
复制代码
@Provides
@ActivityScoped
public MyDependency provideMyDependency() { ... }
复制代码
@EntryPoint
@InstallIn(SingletonComponent.class)
public interface MyEntryPoint {
    MyDependency getMyDependency();
}
// 在非 Hilt 类中使用
MyEntryPoint entryPoint = EntryPointAccessors.fromApplication(context, MyEntryPoint.class);
MyDependency dep = entryPoint.getMyDependency();
复制代码
@HiltViewModel
public class MyViewModel extends ViewModel {
    private final UserRepository userRepository;
    @Inject
    public MyViewModel(UserRepository userRepository) { // 依赖注入
        this.userRepository = userRepository;
    }
}
// 在 Activity/Fragment 中获取 (使用 by viewModels())
相关推荐
龚子亦几秒前
【Unity开发】安卓应用开发中,用户进行权限请求
android·unity·安卓权限
共享家952715 分钟前
MySQL-基础查询(下)
android·mysql
查克陈Chuck41 分钟前
Launcher3模块化-组件化
android·launcher开发
千里马学框架44 分钟前
google官方文档:深入剖析ProtoLog原理及Winscope的查看方式
android·车载系统·framework·perfetto·系统开发·winscope
apihz1 小时前
获取当前北京时间的免费API接口教程
android
apihz1 小时前
货币汇率换算免费API接口(每日更新汇率)
android·java·开发语言
恋猫de小郭1 小时前
八年开源,GSY 用五种技术开发了同一个 Github 客户端,这次轮到 AI + Compose
android·前端·flutter
sc.溯琛9 小时前
MySQL 高级实战:触发器、事务与数据库备份恢复全攻略
android·adb
zhuzewennamoamtf10 小时前
Linux SPI设备驱动
android·linux·运维
雨声不在13 小时前
gradle编译missing_rules报错处理
android·gradle·agp8