Jetpack实际项目中使用到依赖注入:Hilt

目录

  1. 是什么
  2. 为什么使用
  3. 基本使用
  4. 知识点:接口的依赖注入,第三方接口的依赖注入

一、是什么?

随着技术的更新迭代,Android端,也开始使用上了依赖注入。我也是开始要做一个新的项目,进行技术选型的时候,了解了这个技术。Hilt是一个功能强大且用法简单的依赖注入框架。

依赖注入,和后台开发用到的是一样的。从以前我们来new对象,现在变为别人帮助我们new好,我们直接使用就可以。

二、基本使用

2.1.引入依赖

    implementation "com.google.dagger:hilt-android:2.44"
    kapt "com.google.dagger:hilt-android-compiler:2.44"

2.2.Hilt的简单用法:类注入。

(1)加上一个@HiltAndroidApp注解,这是使用Hilt的一个必备前提

@HiltAndroidApp
class AppApplication:Application() {
}

(2)我们在Student 类的构造函数上声明了一个@Inject注解,其实就是在告诉Hilt,你可以通过这个构造函数来创建

class Student @Inject constructor(){
    fun getInfo(){
        Log.d("student", "getInfo: ")
    }
}

(3)进行使用

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var student:Student

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main3)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }

        student.getInfo()
    }
}

Hilt一共支持6个入口点,分别是:

    Application
    Activity
    Fragment
    View
    Service
    BroadcastReceiver

其中,只有Application这个入口点是使用@HiltAndroidApp注解来声明的,这个我们刚才已经看过了。其他的所有入口点,都是用@AndroidEntryPoint注解来声明的。如果我们需要在这个类里面进行依赖注入,就需要使用到这个注解。

@Inject注解,表示我希望通过Hilt来注入student这个字段。

三、知识点

3.1 接口的依赖注入

interface CollectService {

    @GET("lg/collect/list/{page}/json")
    suspend fun getCollectList(@Path("page") page: Int): BaseModel<Collect>

}
@AndroidEntryPoint
class MainActivity : BaseActivity<HomeActivityMainBinding, MainViewModel>() {

 @Inject
    lateinit var mApi: CollectService 

}

那么这个实例是哪里来的呢?如下:

@Module //声明一个@Module注解,表示这一个用于提供依赖注入实例的模块。
@InstallIn(SingletonComponent::class)//ilt 这个模块中定义的依赖项将被安装在应用程序的全局单例组件中。这意味着这些依赖项将在整个应用程序的生命周期内只被创建一次,并在所有需要它们的地方共享。
class DIHomeNetServiceModule {

    /**
     * Home模块的[HomeApiService]依赖提供方法
     *
     * @param retrofit Retrofit
     * @return HomeApiService
     */
    @Singleton//@Singleton 注解也用于 provideDatabase 方法上,以确保返回的 AppDatabase 实例是单例的。
    @Provides//表示provideHomeApiService方法是一个提供依赖项的方法
    fun provideHomeApiService(retrofit: Retrofit): HomeApiService {
        return retrofit.create(HomeApiService::class.java)
    }
}

@HiltViewModel是什么意思

@HiltViewModel 是 Hilt 库中的一个注解,它用于 Android 开发中,特别是在使用 ViewModel 架构组件时。ViewModel 是 Android Jetpack 架构组件的一部分,旨在存储和管理界面相关的数据。ViewModel 的主要目的是在配置更改(如屏幕旋转)期间保持数据。

然而,ViewModel 需要通过某种方式被实例化并注入到 Fragment 或 Activity 中。在不使用依赖注入框架(如 Hilt)的情况下,这通常是通过 ViewModelProvider 来手动完成的。但是,使用 Hilt 可以使这个过程更加简洁和自动化。

@HiltViewModel 注解的作用是将 ViewModel 标记为可以由 Hilt 管理的依赖项。当你将 @HiltViewModel 注解添加到 ViewModel 类上时,Hilt 会自动处理 ViewModel 的创建和注入过程。这样,你就不需要手动调用 ViewModelProvider 来获取 ViewModel 实例了。

下面是一个使用 @HiltViewModel 注解的简单示例:

import androidx.lifecycle.ViewModel  
import dagger.hilt.android.lifecycle.HiltViewModel  
import javax.inject.Inject  
  
@HiltViewModel  
class MyViewModel @Inject constructor(  
    // 可以在这里注入其他依赖项  
    private val someDependency: SomeDependency  
) : ViewModel() {  
    // ViewModel 的内容  
}

在这个例子中,MyViewModel 被标记为 @HiltViewModel,这意味着它将被 Hilt 管理。构造函数被标记为 @Inject,这样 Hilt 就可以知道在创建 MyViewModel 实例时需要注入哪些依赖项(在这个例子中是 SomeDependency)。

然后,在 Fragment 或 Activity 中,你可以使用 Hilt 提供的 by viewModels() 委托来获取 ViewModel 的实例,而无需手动调用 ViewModelProvider:

import androidx.fragment.app.Fragment  
import dagger.hilt.android.AndroidEntryPoint  
import androidx.lifecycle.viewModelScope  
  
@AndroidEntryPoint  
class MyFragment : Fragment() {  
    private val myViewModel: MyViewModel by viewModels()  
  
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {  
        super.onViewCreated(view, savedInstanceState)  
        // 使用 myViewModel ...  
    }  
}

请注意,为了使 by viewModels() 委托工作,你需要在 Fragment 或 Activity 上添加 @AndroidEntryPoint 注解,这样 Hilt 才能知道这个类是一个需要注入依赖项的入口点。

viewModels()的构造函数的示例是如何传递进去的。自己传递,Hilt回去自动注入。

3.2 第三方的依赖注入

如何给第三方的类进行依赖注入呢?按照前面的流程,我们需要给类加上@Inject来选择要创建实例的方式。这个时候要借助@Module注解了



/**
 * 全局作用域的网络层的依赖注入模块
 */
@Module
@InstallIn(SingletonComponent::class)
class DINetworkModule {

    /**
     * [OkHttpClient]依赖提供方法
     *
     * @return OkHttpClient
     */
    @Singleton
    @Provides
    fun provideOkHttpClient(): OkHttpClient {
        // 日志拦截器部分
        val level = if (BuildConfig.VERSION_TYPE != VersionStatus.RELEASE) BODY else NONE
        val logInterceptor = HttpLoggingInterceptor().setLevel(level)

        return OkHttpClient.Builder()
            .connectTimeout(15L * 1000L, TimeUnit.MILLISECONDS)
            .readTimeout(20L * 1000L, TimeUnit.MILLISECONDS)
            .addInterceptor(logInterceptor)
            .retryOnConnectionFailure(true)
            .build()
    }

    /**
     * 项目主要服务器地址的[Retrofit]依赖提供方法
     *
     * @param okHttpClient OkHttpClient OkHttp客户端
     * @return Retrofit
     */
    @Singleton
    @Provides
    fun provideMainRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .baseUrl(NetBaseUrlConstant.MAIN_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()
    }
}

provideMainRetrofit和provideMainRetrofit()这个函数名是随便定义的,Hilt不做任何要求。

这次我们写的不是抽象函数了,而是一个常规的函数。在这个函数中,按正常的写法去创建OkHttpClient的实例,并进行返回即可。

函数的上方加上@Provides注解,这样Hilt才能识别它。

可以注意到 provideMainRetrofit(okHttpClient: OkHttpClient)的okHttpClient是谁传递?答案是,完全不需要传递,因为这个过程是由Hilt自动完成的。我们所需要做的,就是保证Hilt能知道如何得到一个OkHttpClient的实例,而这个工作我们早在前面一步就已经完成了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前期后期

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值