📜  Dagger 在 Android 中是如何工作的?

📅  最后修改于: 2022-05-13 01:58:44.277000             🧑  作者: Mango

Dagger 在 Android 中是如何工作的?

当我们创建一个的 Android 项目时,最终我们会开始积累不同的依赖项来获得某些功能,但是随着时间的推移管理它们变得很麻烦,因此像 Dagger 这样的注入框架开始发挥作用。但是,设置像 Dagger 这样的注入服务需要大量的样板代码,并且学习曲线非常陡峭。最初在没有 Android 支持的情况下添加 Dagger 的原始依赖项/版本是一场噩梦。

但…..

然后是 Dagger-Android,它改变了这个游戏并满足了原始 Dagger 所缺乏的一切,比如减少了预制(样板)代码,但它仍然没有成功。最近 Dagger-Hilt 在部分知名的 Jetpack 库中发布,现在谷歌也推荐了某种方式来实现。以下是他们提到的使用 Dagger-Hilt 的优点:

  1. 为不同的构建类型和风格提供一组不同的绑定。
  2. 使原始 Dagger 代码对开发人员来说简单易读。
  3. 负责在哪里注入依赖项
  4. 所有发生的剩余代码都由匕首本身通过使用注释来处理,从而删除所有样板代码。

但是,问题仍然存在……

匕首如何工作?

为此,让我们看一下这个简短的故事:

介绍一下: Android 开发者Spadan和他开发的机器人 Zen

斯潘丹可能是一个神秘的人,但也可能是一个过分孤独的人……

现在有两个主要特点:

  • 当被问到“你好吗?
  • 在斯潘丹的公寓周围走动,避开障碍物。

为了开发 Zen,Spandan没有使用依赖注入。

结果:Zen 可以快速发挥作用,并且非常容易地执行其功能(走路和说话)。

有一天,Spandan 想要改变 Zen 的行为,因为嗯……有一个在家里走动的机器人很好,但现在他做的不多,对吧?

出于这个原因,我们的开发人员必须忘记他的座右铭“我打扰的越少越好” 。的确,无论是改变 Zen 的行为还是测试他的代码,他都必须接触他的代码。如果它的代码是足够模块化的,这将对其有很大帮助。但是仅在测试期间切换 Zen 的行为,问题并没有解决。

幸运的是,Spandan 终于发现了依赖注入!对他的启示!是的,排队需要更长的时间,但一旦完成,不再头疼!事实上,Spandan 将他的机器人分成几个不同且独立的部分(或模块):顶部、右臂、左臂等。这些都将添加到 Zen 的身体中,而另一方面,Zen 需要这些部分来函数。

Zen 的新依赖(都在不同的部分)

Zen 所依赖的这些不同部分称为依赖项。这些是独立于他的身体创建的,它们将被“注入”到他的代码中。也就是说,它们只是简单地“连接”到 Zen 的身体,它可以使用它们来控制和说话。这意味着,例如,如果 Spandan 希望 Zen 需要利用他的乘车时间来洗碗,他只需修改相应的依赖项(这里是武器中的一个)。此外,当Spandan 想对Buggy 进行不同的函数测试时,他会特别针对这种情况定义依赖关系,并改变机器人的行为以使其在“行走”功能测试期间保持不动。

了解匕首

在开始使用 Dagger-Hilt 之前,我们想了解 Dagger 的基础知识。在本节中,您将了解 Dagger 及其术语。基本上,要了解 Dagger 我们必须知道 4 个主要注解,

  1. 模块
  2. 零件
  3. 提供
  4. 注入

为了在基础课程中更好地理解它,请将模块视为依赖项的提供者,并将活动或其他类视为消费者。现在为了提供从提供者到消费者的依赖关系,我们在它们之间建立了一座桥梁,在 Dagger 中,组件作为特定的桥梁。

现在,一个模块可能是一个类,我们用@Module注释它以便 Dagger 知道它是模块。组件是一个接口,它使用@Component注释并在其中接受模块。 (但现在,Dagger-Hilt 不需要此注释)。 Inject 是一个注释,它不会在买方内部定义依赖关系。

通过流程图了解 Dagger

#1。建立一个新的项目

创建项目

  1. 选择空活动然后下一步
  2. 名称:GeeksforGeeksDaggerTutorial
  3. :com.geeksforgeeks.dagger
  4. 语言:科特林
  5. 结束

您的起始项目现已准备就绪

#2。添加依赖项

在应用程序的 build.gradle 文件中添加后续依赖项:

您的初始Gradle文件现已准备就绪!

#3。我们需要枚举来表示 UI 状态。我们将在 utils 包中创建它。

Kotlin
package com.geeksforgeeks.dagger.utils
  
enum class Status {
    SUCCESS,
    ERROR,
    LOADING
}


Kotlin
package com.geeksforgeeks.dagger.utils
  
data class Resource(val status: Status, val data: T?, val message: String?) {
  
    companion object {
  
        fun  success(data: T?): Resource {
            return Resource(Status.SUCCESS, data, null)
        }
  
        fun  error(msg: String, data: T?): Resource {
            return Resource(Status.ERROR, data, msg)
        }
  
        fun  loading(data: T?): Resource {
            return Resource(Status.LOADING, data, null)
        }
    }
}


现在我们需要一个实用程序类来处理网络调用的当前状态到用户界面 (UI) 层的通信。我们(对于这个项目)将其命名为Resource

#4。在同一个 utils 包中创建一个 Kotlin 类“Resource.kt”并添加以下代码:

科特林

package com.geeksforgeeks.dagger.utils
  
data class Resource(val status: Status, val data: T?, val message: String?) {
  
    companion object {
  
        fun  success(data: T?): Resource {
            return Resource(Status.SUCCESS, data, null)
        }
  
        fun  error(msg: String, data: T?): Resource {
            return Resource(Status.ERROR, data, msg)
        }
  
        fun  loading(data: T?): Resource {
            return Resource(Status.LOADING, data, null)
        }
    }
}

我们现在已经准备好使用这个包了!希望你通过这篇文章得到真正的香气,并且会很好地理解匕首是如何工作的🙂