学习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())
相关推荐
小兔薯了6 小时前
7. LNMP-wordpress
android·运维·服务器·数据库·nginx·php
L***d6707 小时前
mysql的主从配置
android·mysql·adb
Sammyyyyy8 小时前
PHP 8.5 新特性:10 大核心改进
android·php·android studio
TO_ZRG8 小时前
Unity 通过 NativePlugin 接入Android SDK 指南
android·unity·游戏引擎
n***84079 小时前
Springboot-配置文件中敏感信息的加密:三种加密保护方法比较
android·前端·后端
方白羽10 小时前
一次由 by lazy 引发的“数据倒灌”,深入理解 `by`关键字、`lazy`函数的本质
android·kotlin·app
v***553410 小时前
MySQL 中如何进行 SQL 调优
android·sql·mysql
vx_vxbs6612 小时前
【SSM高校普法系统】(免费领源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
android·java·python·mysql·小程序·php·idea
j***827013 小时前
【MyBatisPlus】MyBatisPlus介绍与使用
android·前端·后端
ljt272496066113 小时前
Compose笔记(五十八)--LinearOutSlowInEasing
android·笔记·android jetpack