学习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())
相关推荐
alexhilton2 分钟前
在Jetpack Compose中创建CRT屏幕效果
android·kotlin·android jetpack
2501_940094022 小时前
emu系列模拟器最新汉化版 安卓版 怀旧游戏模拟器全集附可运行游戏ROM
android·游戏·安卓·模拟器
下位子2 小时前
『OpenGL学习滤镜相机』- Day9: CameraX 基础集成
android·opengl
参宿四南河三4 小时前
Android Compose SideEffect(副作用)实例加倍详解
android·app
火柴就是我5 小时前
mmkv的 mmap 的理解
android
没有了遇见5 小时前
Android之直播宽高比和相机宽高比不支持后动态获取所支持的宽高比
android
shenshizhong5 小时前
揭开 kotlin 中协程的神秘面纱
android·kotlin
vivo高启强6 小时前
如何简单 hack agp 执行过程中的某个类
android
沐怡旸6 小时前
【底层机制】 Android ION内存分配器深度解析
android·面试
你听得到116 小时前
肝了半个月,我用 Flutter 写了个功能强大的图片编辑器,告别image_cropper
android·前端·flutter