学习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())
相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui