文章目录
- 官方文档
- 添加依赖
- 初始化hilt
- MainActivity 使用
- 共享类
- 在 `MainActivity` 添加依赖注入
- @ActivityScoped 作用域
- @Singleton 作用域
- 构造参数,添加 Context参数@ApplicationContext、@ActivityContext
官方文档
https://developer.android.com/training/dependency-injection/hilt-android#groovy
demo 如下:
https://gitee.com/zhaoyanjun/hilt
添加依赖
在根目录 build.gradle
的添加 hilt 插件
plugins {
...
id 'com.google.dagger.hilt.android' version '2.44' apply false
}
完整如下:
plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
//添加hilt 依赖
id 'com.google.dagger.hilt.android' version "2.44" apply false
}
在 app 的 build.gradle
,的 plugins
目录添加
...
plugins {
id 'kotlin-kapt'
id 'com.google.dagger.hilt.android'
}
android {
...
}
dependencies {
implementation "com.google.dagger:hilt-android:2.44"
kapt "com.google.dagger:hilt-compiler:2.44"
}
// Allow references to generated code
kapt {
correctErrorTypes true
}
初始化hilt
在 Application
添加 @HiltAndroidApp
注解
@HiltAndroidApp
public class App extends Application {
}
MainActivity 使用
共享类
使用 @Inject
注解作用在类的构造函数中
public class Util {
String token = "1234444";
@Inject
public Util() {
}
}
在 MainActivity
添加依赖注入
在 MainActivity
类中添加 @AndroidEntryPoint
注解
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
}
在 android 项目中,但凡一个类要使用 hilt 依赖注入能力,就要在类头部加入 @AndroidEntryPoint
注解
使用 @Inject
申明需要使用的注入类
@Inject
lateinit var appToken: Util
完整的代码如下:
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var appToken: Util
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<TextView>(R.id.tv).text = appToken.token
}
}
这样例子就可以跑起来了。
但是这里有个问题,每一个申明 @Inject lateinit var appToken: Util
的对象都是一个新对象,如果我们要想在 Activity 作用域中实现对象共享,类似于 jetpack 中的 viewModel 。我么需要 @ActivityScoped
注解
@ActivityScoped 作用域
代码如下:
@ActivityScoped
public class Util {
String token = "1234444";
@Inject
public Util() {
}
}
使用 @ActivityScoped
修饰的注入类,在 Activity 类多次申明注入,得到的实例只有一个。
@Singleton 作用域
全局单例作用域
@Singleton
public class Util {
String token = "1234444";
Context context;
@Inject
public Util(@ApplicationContext Context context) {
this.context = context;
}
public String getName() {
return context.getResources().getString(R.string.app_name);
}
}
构造参数,添加 Context参数@ApplicationContext、@ActivityContext
如果是 Activity 实例的 context , 需要添加 @ActivityContext
public class Util {
String token = "1234444";
Context context;
@Inject
public Util(Context context) {
this.context = context;
}
public String getName() {
return context.getResources().getString(R.string.app_name);
}
}
但是这种已编译就报错
解决也很好弄,在 Context 上添加 @ApplicationContext
注解,代码如下:
public class Util {
String token = "1234444";
Context context;
@Inject
public Util(@ApplicationContext Context context) {
this.context = context;
}
public String getName() {
return context.getResources().getString(R.string.app_name);
}
}
添加 @ApplicationContext
注解后,Context 参数就会自动添加。
如果是 Activity 实例的 context , 需要添加 @ActivityContext
, 代码如下:
public class Util {
String token = "1234444";
Context context;
@Inject
public Util(@ActivityContext Context context) {
this.context = context;
}
public String getName() {
return context.getResources().getString(R.string.app_name);
}
}