【Android官网学习】依赖注入DI

什么是依赖注入

类通常需要引用其他类。例如,Car 类可能需要引用 Engine 类。这些必需类称为依赖项,在此示例中,Car 类依赖于拥有 Engine 类的一个实例才能运行。

类可通过以下三种方式获取所需的对象:

  1. 类构造其所需的依赖项。类创建并初始化自己的依赖类型的实例。
  2. 从其他地方抓取。某些 Android API(如Contextgetter 和 getSystemService())的工作原理便是如此。
  3. 参数形式提供。应用可以在构造类时提供这些依赖项,或者将这些依赖项传入需要各个依赖项的函数。

第三种方式就是依赖项注入。

依赖注入的优点

总的来说:易于复用,易于重构,方便测试

重用类以及分离依赖项:更容易换掉依赖项的实现。由于控制反转,代码重用得以改进,并且类不再控制其依赖项的创建方式,而是支持任何配置。比如Car依赖Engine,那么将Engine作为依赖注入,而不是Car中创建Engine实例。如果有Engine的子类想要用Car,则可以直接使用。

易于重构:依赖项成为 API Surface 的可验证部分,因此可以在创建对象时或编译时进行检查,而不是作为实现详情隐藏。

易于测试:类不管理其依赖项,因此在测试时,可以传入不同的实现以测试所有不同用例。

Android 中有两种主要的依赖项注入方式

  1. 构造函数注入
  2. 字段注入(setter注入)

这两种都是手动依赖项的注入。有如下缺陷:

1,对于大型应用,获取所有依赖项并正确连接它们可能需要大量样板代码。在多层架构中,要为顶层创建一个对象,必须提供其下层的所有依赖项。例如,要制造一辆真车,可能需要引擎、传动装置、底盘以及其他部件;而要制造引擎,则需要汽缸和火花塞。

2,如果您无法在传入依赖项之前构造依赖项(例如,当使用延迟初始化或将对象作用域限定为应用流时),则需要编写并维护管理内存中依赖项生命周期的自定义容器(或依赖关系图)。

自动注入依赖项

一,两种思路

  1. 基于反射的解决思路,在运行时连接依赖项
  2. 静态解决方案,可生成在编译时连接依赖项的代码

二,服务定位器 ServiceLocator
使用服务定位器模式,类可以控制并请求注入对象;使用依赖项注入,应用可以控制并主动注入所需对象。

class ServiceLocator {

    private static ServiceLocator instance = null;

    private ServiceLocator() {}

    public static ServiceLocator getInstance() {
        if (instance == null) {
            synchronized(ServiceLocator.class) {
                instance = new ServiceLocator();
            }
        }
        return instance;
    }

    public Engine getEngine() {
        return new Engine();
    }
}

class Car {

    private Engine engine = ServiceLocator.getInstance().getEngine();

    public void start() {
        engine.start();
    }
}

class MyApp {
    public static void main(String[] args) {
        Car car = new Car();
        car.start();
    }
}

服务定位器其实会有以下问题:

  1. 服务定位器所需的依赖项集合使得代码更难测试,因为所有测试都必须与同一全局服务定位器进行交互。

  2. 依赖项在类实现中编码,而不是在 API Surface 中编码。因此,很难从外部了解类需要什么。所以,更改 Car或服务定位器中可用的依赖项可能会导致引用失败,从而导致运行时或测试失败。

  3. 如果您想将作用域限定为除了整个应用的生命周期之外的任何区间,就会更难管理对象的生命周期。

三,Dagger

Dagger 是适用于 Java、Kotlin 和 Android 的热门依赖项注入库,由 Google 进行维护。Dagger 为您创建和管理依赖关系图,从而便于您在应用中使用 DI。它提供了完全静态和编译时依赖项,解决了基于反射的解决方案(如 Guice)的诸多开发和性能问题。

四,Hilt

Hilt 是推荐用于在 Android 中实现依赖项注入的 Jetpack 库。Hilt 通过为项目中的每个 Android 类提供容器并自动为您管理其生命周期,定义了一种在应用中执行 DI 的标准方法。

**Hilt 在热门 DI 库 Dagger 的基础上构建而成,**因而能够受益于 Dagger 提供的编译时正确性、运行时性能、可伸缩性和 Android Studio 支持。

参考

https://developer.android.google.cn/training/dependency-injection#java
https://dagger.dev/

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值