击剑编排软件_探索击剑:Android依赖注入库

击剑编排软件

什么是依赖注入? (What Is Dependency Injection?)

Dependency Injection (DI) is widely being used in programming for quite a long time. DI is a technique by which a class receives other objects that it depends on instead of creating them by itself. Implementing dependency injection provides you with the following advantages:

依赖注入(DI)在编程中已广泛使用了很长时间。 DI是一种技术,通过该技术,类可以接收其依赖的其他对象,而不是自己创建它们。 实现依赖项注入为您提供以下优点:

  • Reusability of code

    代码的可重用性
  • Ease of refactoring

    易于重构
  • Ease of testing

    易于测试

依赖注入的基础 (Fundamentals of Dependency Injection)

While developing an application, a class may require references to other classes. For example, a Car class may need a reference of an Engine class. These required classes are called dependencies, and in this example, the Car class is dependent on having an instance of the Engine class to run. We can provide these required dependencies in three different ways:

在开发应用程序时,一个类可能需要引用其他类。 例如, Car类可能需要引用Engine类。 这些必需的类称为依赖项,在此示例中, Car类依赖于具有要运行的Engine类的实例。 我们可以通过三种不同方式提供这些必需的依赖项:

  1. The dependent class creates the instances or objects of dependencies inside it. In our case, creating the object of Engine class inside the Car class.

    依赖类在其内部创建依赖项的实例或对象 。 在我们的例子中,在Car类中创建Engine类的对象。

  2. Using the objects from somewhere else. The way we useContext and getSystemService() getters.

    从其他地方使用对象。 我们使用ContextgetSystemService()方法的方式。

  3. Providing dependencies as parameters to dependent classes. In our case passing Engine object as a parameter to Car class either through constructor or setter functions.

    将依赖项作为参数提供给依赖类。 在我们的案例中,通过构造函数或设置函数将Engine对象作为参数传递给Car类。

DI is well suited for Android development. If you have ever used Dagger, the official DI framework, or any other DI library for Android, you will know how much effort and boilerplate code it would take to create all required dependencies manually. For me, at the start point of using Dagger, it was like a nightmare to understand and implement things. It took many days to understand things and a lot more to implement them efficiently.

DI非常适合Android开发。 如果您曾经使用过Dagger,官方的DI框架或任何其他用于Android的DI库,您将知道手动创建所有必需的依赖项将花费多少精力和样板代码。 对我而言,在开始使用Dagger时,理解和实现事物就像一场噩梦。 花了很多天来了解事物,花了很多时间才能有效地实现它们。

Dagger-Hilt简介 (Introduction to Dagger-Hilt)

Because of the amount of boilerplate code and the difficulty level of implementation in the current DI libraries, the Android team has come up with Hilt. Hilt provides a standard way to implement DI in Android applications by providing containers for every Android class in our project and managing their lifecycles automatically. Hilt was built on top of Dagger to reduce the effort of doing manual DI in the project and to get benefits from the compile-time correctness, runtime performance, scalability, etc.

由于当前的DI库中包含大量样板代码和实现难度,因此Android团队提出了Hilt。 通过为项目中的每个Android类提供容器并自动管理其生命周期,Hilt提供了一种在Android应用程序中实现DI的标准方法。 Hilt建立在Dagger之上,以减少在项目中执行手动DI的工作,并从编译时正确性,运行时性能,可伸缩性等中受益。

Hilt is a simplified form of Dagger for DI in Android apps with many more benefits.

Hilt是Dagger的简化形式,可用于Android应用程序中的DI,具有更多优势。

As most of us are now adopted to Jetpack’s components, Hilt is now Jetpack’s recommended library for dependency injection in Android. Hilt was developed for Android with an intention to save time for developers.

由于我们大多数人现在都被Jetpack的组件所采用,因此Hilt现在是Jetpack 推荐的Android中依赖项注入的库。 Hilt是为Android开发的,旨在为开发人员节省时间。

为什么要击剑? (Why Hilt?)

The primary goal of Hilt is to simplify Dagger-related infrastructure for Android apps. The benefits of Hilt are:

Hilt的主要目标是简化Android应用程序与Dagger相关的基础架构。 Hilt的好处是:

  • Reduced boilerplate

    减少样板
  • Decoupled build dependencies

    解耦的构建依赖项
  • Simplified configuration

    简化配置
  • Improved testing

    改进测试

击剑基础 (Hilt Basics)

Before hitting implementation, let’s check the terminology related to Hilt. Similar to Dagger, Hilt is a completely annotation-based framework. A few annotations that we use frequently are:

在开始实施之前,让我们检查一下与Hilt相关的术语。 与Dagger相似,Hilt是一个完全基于注释的框架。 我们经常使用的一些注释是:

@HiltAndroidApp (@HiltAndroidApp)

This annotation needs to be applied to the application class so the component gets generated. Isn’t that easy compared to Dagger?

该注释需要应用于应用程序类,以便生成组件。 和Dagger相比不容易吗?

@HiltAndroidApp
class ExampleApplication : Application() { ... }

@AndroidEntryPoint (@AndroidEntryPoint)

This annotation needs to be applied to the Android components like fragments, activities, etc. to inject the dependencies.

需要将此注释应用于片段,活动等Android组件,以注入依赖关系。

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() { ... }

Hilt currently supports the following Android classes:

Hilt当前支持以下Android类:

  • Activity

    Activity

  • Fragment

    Fragment

  • View

    View

  • Service

    Service

  • BroadcastReceiver

    BroadcastReceiver

@Inject (@Inject)

This annotation is used to perform the injection. It is used to inject the dependencies into dependent classes. The dependencies can be injected through a constructor, field, or method. This is similar in Dagger.

该注释用于执行注入。 它用于将依赖项注入到依赖类中。 可以通过构造函数,字段或方法注入依赖项。 这在Dagger中类似。

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {


  @Inject lateinit var analytics: Analytics
  ...
}
class SampleAdapter @Inject constructor(
  private val service: SampleService
) { ... }

Fields injected by Hilt cannot be private.

Hilt注入的字段不能为私有。

@Module (@Module)

This annotation is used above the class where we provide dependencies, i.e., where we create objects. This is similar in Dagger.

在提供依赖项的类(即创建对象的类)上方使用了此注释。 这在Dagger中类似。

@InstallIn (@InstallIn)

The Hilt module annotated with @InstallIn(ActivityComponent::class) because we want Hilt to inject that dependency into Activity class. This annotation means that all of the dependencies in thisModule are available in all of the app’s activities.

@InstallIn ( ActivityComponent::class )注释的Hilt模块,因为我们希望Hilt将该依赖项注入Activity类。 此注释意味着此Module中的所有依赖项在所有应用程序活动中均可用。

@Module
@InstallIn(ActivityComponent::class)
abstract class ExampleModule {
....
....  
}

@提供 (@Provides)

The annotation is used in the modules and above the methods where we create objects to pass them as dependencies. This annotation is similar to that in Dagger. It’s mostly used to provide third-party library instances.

注释在模块中以及方法的上方使用,我们在其中创建对象以将它们作为依赖项传递。 此注释与Dagger中的注释相似。 它主要用于提供第三方库实例。

@Module
@InstallIn(ActivityComponent::class)
object NetworkModule {


  @Provides
  fun provideExampleService(): ExampleService {
      return Retrofit.Builder()
               .baseUrl("https://example.com")
               .build()
               .create(ExampleService::class.java)
  }
}

提示设定 (Hilt Setup)

First, add the hilt-android-gradle-plugin plugin to your project’s root level build.gradle file:

首先,将hilt-android-gradle-plugin插件添加到项目的根级别build.gradle文件中:

buildscript {
    ...
    ext.hilt_version = '2.28-alpha'
    dependencies {
        ...
        classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
    }
}

Next, apply the Gradle plugin in app/build.gradle file:

接下来,在app/build.gradle文件中app/build.gradle Gradle插件:

apply plugin: 'dagger.hilt.android.plugin'


android {
    ...
}

Finally, add the following dependencies in app/build.gradle file:

最后,在app/build.gradle文件中添加以下依赖app/build.gradle

dependencies {
    ...
    implementation "com.google.dagger:hilt-android:$hilt_version"
    kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
}

Environment setup to start using Hilt was done. Once we build and sync the project, we can use them. Let’s start using Hilt!

完成了开始使用Hilt的环境设置。 构建并同步项目后,就可以使用它们了。 让我们开始使用Hilt!

行动中 (Hilt in Action)

Let's check how to inject a simple class into the Application class.

让我们检查一下如何将一个简单的类注入Application类。

class ExampleClass @Inject constructor() {


    fun doSomeWork() {
        Log.d("HiltApp", "Do some work")
    }
}




//Injecting the above ExampleClass into application 
@HiltAndroidApp
class ExampleApplication : Application() {


    @Inject
    lateinit var exampleClass: ExampleClass
    
   @Override public void onCreate() {
    super.onCreate(); // Injection happens in super.onCreate()
    // Use exampleClass
  }
}

To tell Hilt how to provide instances of a type, add the @Inject annotation to the constructor of the class you want to be injected. The information that Hilt has about how to provide instances of different types is also called bindings.

要告诉Hilt如何提供类型的实例,请将@Inject批注添加到要注入的类的构造函数中。 Hilt关于如何提供不同类型的实例的信息也称为绑定

Once we have enabled members injection in our Application, we can start enabling members injection in our other Android classes using the @AndroidEntryPoint annotation.

一旦在Application启用了成员注入,就可以使用@AndroidEntryPoint批注开始在其他Android类中启用成员注入。

@AndroidEntryPoint
class SampleActivity : BaseActivity() {
   @Inject
   lateinit var exampleClass: ExampleClass // Bindings in ActivityComponent


   override fun onCreate() {
    // Injection happens in super.onCreate().
    super.onCreate()


    // Do something with exampleClass ...
   }
}

Hilt附带Jetpack支持 (Hilt Comes with Jetpack Support)

As most of us started using the Jetpack libraries, Hilt for Jetpack support needs some additional dependencies.

当我们大多数人开始使用Jetpack库时,Hilt for Jetpack支持还需要一些其他依赖项。

dependencies {
  ...
  implementation "androidx.fragment:fragment-ktx:1.2.4"
  implementation 'androidx.hilt:hilt-lifecycle-viewmodel:$hilt_jetpack_version'
  kapt 'androidx.hilt:hilt-compiler:$hilt_jetpack_version'
  kaptAndroidTest 'androidx.hilt:hilt-compiler:$hilt_jetpack_version'
}

Hilt currently supports the following Jetpack components:

Hilt当前支持以下Jetpack组件:

  • ViewModel

    ViewModel

  • WorkManager

    WorkManager

Let’s take a look at creating simple ViewModel and injecting it in an Activity. @ViewModelInject annotation is used in the ViewModel object’s constructor to provide a ViewModel instance.

让我们来看看创建简单的ViewModel并将其注入到Activity中。 @ViewModelInject批注用于ViewModel对象的构造函数中,以提供ViewModel实例。

class SampleViewModel @ViewModelInject constructor(
  private val sampleRepo: SampleRepo
): ViewModel { ... }

Injection of this ViewModel into Activity is far more simple with a single line of code:

只需一行代码,即可将此ViewModel注入Activity更加简单:

private val sampleViewModel: SampleViewModel by viewModels()

viewModels() is a delegate function that can be used to inject a ViewModel. Here there is no need of using @Inject annotation. If we want to use the Activitylevel ViewModel, we need to apply the activityViewModels() delegate function instead of viewModels().

viewModels() 是可用于注入ViewModel的委托函数。 此处无需使用@Inject批注。 如果要使用Activity级别的ViewModel ,则需要应用activityViewModels ()委托函数而不是viewModels ()

Entire Activity may look something like this:

整个活动可能如下所示:

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
  private val sampleViewModel: SampleViewModel by viewModels()
  ...
}

Learn more about Jetpack support in the docs.

文档中了解有关Jetpack支持的更多信息。

Isn’t it fun to inject the components in the simplest way? People who started using initial versions of Dagger would understand how easy it was using Hilt compared to Dagger. However, it was an overlay layer over Dagger, knowing the basics is always an important thing. Start using Hilt.

以最简单的方式注入组件不是很有趣吗? 开始使用Dagger初始版本的人会明白,与Dagger相比,使用Hilt是如此容易。 但是,它是Dagger的覆盖层,了解基础知识始终是重要的事情。 开始使用Hilt。

Please let me know your suggestions and comments.

请让我知道您的建议和意见。

Thanks for reading!

谢谢阅读!

翻译自: https://medium.com/better-programming/hilt-dependency-injection-library-for-android-2aebf04e8147

击剑编排软件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值