Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android |《看完不忘系列》之dagger

Android |《看完不忘系列》之dagger

作者头像
Holiday
发布于 2020-09-03 08:38:11
发布于 2020-09-03 08:38:11
1K00
代码可运行
举报
文章被收录于专栏:哈利迪ei哈利迪ei
运行总次数:0
代码可运行

嗨,我是哈利迪~《看完不忘系列》将以从树干到细枝的思路分析一些技术框架,本文将对开源项目dagger进行介绍。

本文约3800字,阅读大约10分钟。 Dagger源码基于最新版本2.28.3

背景

依赖注入(Dependency Injection,DI)遵循控制反转(Inversion of Control,IoC)原则,简单来说就是创建对象时给对象传入依赖,通过传入不同实例来实现不同行为(控制),比如常见的构造方法和setter都叫注入。

简单概括一下谷歌的造车栗子,

一、不注入,由Car类自己创建依赖的Engine实例,当需要替换汽车引擎时,需要修改Car类,违背了开放封闭原则,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Car {
    private Engine engine = new Engine();
}

二、手动依赖注入,如构造方法和setter,当需要替换汽车引擎时,传入不同的引擎实现(如ElectricEngine extends Engine)即可,无需修改Car类,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//1.构造方法注入
class Car {
    private final Engine engine;
    
    public Car(Engine engine) {
        this.engine = engine;
    }
}

//2.setter注入
class Car {
    private Engine engine;

    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}

三、随着汽车配件变多,依赖注入的代码也会越来越多,如汽车需要引擎、轮胎,引擎又需要气缸和火花塞,这样一层层下去注入代码成指数级上升,出现了大量创建对象的样板代码,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Car {
    private final Engine engine;//引擎
    private final Wheel wheel;//轮胎

    public Car(Engine engine,Wheel wheel) {
        this.engine = engine;
        this.wheel = wheel;
    }
}

class Engine {
    private final Cylinder cylinder;//气缸
    private final SparkPlug sparkPlug;//火花塞

    public Car(Cylinder cylinder,SparkPlug sparkPlug) {
        this.cylinder = cylinder;
        this.sparkPlug = sparkPlug;
    }
}

void main(){
    //为了造辆车,要new出一堆对象,还要构造方法注入,套娃既视感
    Cylinder cylinder = new Cylinder();
    SparkPlug sparkPlug = new SparkPlug();
    Engine engine = new Engine(cylinder,sparkPlug);
    Wheel wheel = new Wheel();
    Car car = new Car(engine,wheel);
}

从代码可以看出有两大痛点,一是要创建很多对象,二是对象的创建过程还需有序,即要先有气缸和火花塞才能造引擎,先有引擎和轮胎才能造车,这样使用方还需花时间了解配件间的依赖关系,很是不便。

于是就有了一些库来实现自动依赖注入,有两个实现思路(koin的实现以后再聊~),

  1. 一是运行期反射连接依赖项,编译影响小,但运行慢
  2. 二是编译期就连接依赖项,创建辅助类需要额外的io和编译耗时,会拖慢编译速度,但运行快

Android内存和算力都有限的终端设备,dagger当然是选择思路2啦。dagger通过注解标记对象创建姿势依赖关系作用域等信息,在编译期创建辅助类,从而实现自动依赖注入。不过dagger的上手成本略高,谷歌后来又推出了Hilt,旨在让我们用得舒心

Hilt 是推荐用于在 Android 中实现依赖项注入的 Jetpack 库。Hilt 通过为项目中的每个 Android 类提供容器并自动为您管理其生命周期,定义了一种在应用中执行 DI 的标准方法。 Hilt 在热门 DI 库 Dagger 的基础上构建而成,因而能够受益于 Dagger 提供的编译时正确性、运行时性能、可伸缩性和 Android Studio 支持。 -- 谷歌

Hilt就先放一放,下面我们先开始dagger之旅吧~

补:关于手动注入的痛点,可以看下谷歌的手动依赖项注入(看完或许能更好的理解dagger的设计)。

树干

简单使用

依赖,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
implementation 'com.google.dagger:dagger:2.28.3'
annotationProcessor 'com.google.dagger:dagger-compiler:2.28.3'
@Inject和@Component

@Inject标记实例的创建姿势,汽车和引擎类,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Car {
    private final Engine mEngine;

    @Inject //告诉dagger如何创建Car
    public Car(Engine engine) {
        mEngine = engine;
    }

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

class Engine {
    @Inject //告诉dagger如何创建Engine
    public Engine() {
    }

    public void start() {
        Log.e("哈利迪", "引擎发动,前往秋名山");
    }
}

这样dagger就能生成类似 new Car(new Engine()) 的代码来创建实例,

@Component标记所要创建的实例有哪些,如在造车图纸(接口)里声明要造车,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component //告诉dagger要造啥
interface CarGraph {
    //造车
    Car makeCar();
}

make一下项目,生成Car_Factory、Engine_Factory和DaggerCarGraph三个类,在Activity中使用,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class DaggerActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dagger);
        //得到造车图纸
        CarGraph carGraph = DaggerCarGraph.create();
        //造出一辆汽车
        Car car = carGraph.makeCar();
        //引擎发动
        car.start();
    }
}

注入姿势二,还可以直接把汽车注入给Activity,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component //告诉dagger要造啥
public interface CarGraph {
    //造车
    Car makeCar();

    //新增:告诉dagger有个Activity要注入
    void inject(DaggerActivity activity);
}

make一下,这时会多出一个类DaggerActivity_MembersInjector(成员注入器),我们后面再看,在Activity中,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class DaggerActivity extends AppCompatActivity {
    //向Activity注入汽车
    @Inject
    Car mCar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dagger);
        //得到造车图纸
        CarGraph carGraph = DaggerCarGraph.create();
        //告诉dagger有个Activity要注入
        carGraph.inject(this);
        //此时,mCar已被dagger自动赋值,我们可以直接发动引擎
        mCar.start();
    }
}

不管是哪种姿势,都可以看出,Activity只管提车,无需关心造车内部的细节(用了什么引擎),这样以后要换引擎了,Activity和Car也不用改动代码。

@Module和@Binds

那么问题来了,通常我们都是面向接口编程,现在想把Engine换成IEngine接口咋整呢?因为我有两种引擎,分别是汽油车的GasEngine,和电动车的ElectricEngine,接口没有构造方法怎么注入?此时@Module和@Binds注解就派上用场了。

定义引擎接口和实现类,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface IEngine {
    public void start();
}

class GasEngine implements IEngine {//汽油引擎
    @Inject
    public GasEngine() {
    }

    @Override
    public void start() {
        Log.e("哈利迪", "汽油 引擎发动,前往秋名山");
    }
}

class ElectricEngine implements IEngine {//电动引擎
    @Inject
    public ElectricEngine() {
    }

    @Override
    public void start() {
        Log.e("哈利迪", "电动 引擎发动,前往秋名山");
    }
}

然后Car我们不要了,新写一个汽车类NewCar,让他依赖于接口IEngine而非类,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class NewCar {
    //依赖于接口
    private final IEngine mEngine;

    @Inject //告诉dagger如何创建NewCar
    public NewCar(IEngine engine) {
        mEngine = engine;
    }

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

下面有请@Module和@Binds登场!建一个抽象类GasEngineModule,表示汽油引擎模块,用于提供汽油引擎,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Module
abstract class GasEngineModule {//汽油引擎模块
    @Binds
    abstract IEngine makeGasEngine(GasEngine engine);
}

然后在造车图纸CarGraph里支持一下NewCar的创建,把Module引入Component,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component(modules = {GasEngineModule.class})
//引入汽油引擎模块
public interface CarGraph {
    //...

    //造新车
    NewCar makeNewCar();
}

Activity使用,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//DaggerActivity.java
void onCreate(Bundle savedInstanceState) {
    CarGraph carGraph = DaggerCarGraph.create();
    NewCar newCar = carGraph.makeNewCar();
    newCar.start();
}

搞定~

这时如果想要把NewCar换成电动引擎,直接依赖新的模块即可,新增模块ElectricEngineModule,用于提供电动引擎,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Module
public abstract class ElectricEngineModule {//电动引擎模块
    @Binds
    abstract IEngine makeElectricEngine(ElectricEngine engine);
}

GasEngineModule模块换成ElectricEngineModule,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component(modules = {ElectricEngineModule.class})//替换
public interface CarGraph {
    //...
}

运行就能得到电动车了,可见这个过程我们不需要修改NewCar就能换掉引擎(偷梁换柱)。

@IntoMap和@StringKey

又有一天,突然想开双混动汽车了咋整,就是说汽油引擎和电动引擎我全都要,我们发现@Component的modules可以传入数组,那试试把两个引擎模块都传进去,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component(modules = {GasEngineModule.class, ElectricEngineModule.class})
public interface CarGraph {
    //...
}

make一下,不用想也知道会出错,NewCar只有一个依赖IEngine接口,这时dagger已经不知道,造NewCar到底要传入哪个引擎了,

那怎么办?支持多绑定的@IntoMap和@StringKey登场了。

IntoMap表示会把这个Module存进map里,StringKey表示Module名字,这个名字也会作为map的key,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Module
abstract class GasEngineModule {//汽油引擎模块
    @Binds
    @IntoMap
    @StringKey("Gas")
    abstract IEngine makeGasEngine(GasEngine engine);
}

@Module
abstract class ElectricEngineModule {//电动引擎模块
    @Binds
    @IntoMap
    @StringKey("Electric")
    abstract IEngine makeElectricEngine(ElectricEngine engine);
}

然后修改一下NewCar,此时不再只是依赖一个引擎接口IEngine了,而是一组引擎,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class NewCar {
    //我现在是混动车了,要用map接收引擎
    private final Map<String, IEngine> mEngineMap;

    @Inject //告诉dagger如何创建NewCar
    public NewCar(Map<String, IEngine> engineMap) {
        mEngineMap = engineMap;
    }

    public void start() {
        //双混动走起~
        for (Map.Entry<String, IEngine> entry : mEngineMap.entrySet()) {
            entry.getValue().start();
            //汽油 引擎发动,前往秋名山
            //电动 引擎发动,前往秋名山
        }
    }
}

Activity代码不用改动,双混动车就造好了。

@Singleton

如果想要给双混动NewCar限量全球一款,可以用@Singleton指定为单例,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Singleton //单例,我现在是限量款混动车
public class NewCar {
    //...
}

@Singleton //造车图纸也需跟着单例
@Component(modules = {GasEngineModule.class, ElectricEngineModule.class})
public interface CarGraph {
    //...
}

Activity运行,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//DaggerActivity.java
void onCreate(Bundle savedInstanceState) {
    CarGraph carGraph = DaggerCarGraph.create();
    NewCar newCar = carGraph.makeNewCar();
    newCar.start();
    NewCar newCar2 = carGraph.makeNewCar();
    newCar2.start();
    //newCar和newCar2是同一个实例
    Log.e("哈利迪", newCar.hashCode() + "," + newCar2.hashCode());
}

dagger的使用就先聊到这啦,相信对dagger也已经有了初步认识,还有些注解没讲到,比如:

@Provides:当我们没法用@Inject来标记实例的创建姿势时,可以用@Module和@Provides来提供实例,比如Retrofit是三方库的类我们没法标记其构造方法,则可以用Provides提供,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Module
public class NetworkModule {
    @Provides
    public Retrofit provideRetrofit() {
        return new Retrofit.Builder()
            .baseUrl("xxx")
            .build();
    }
}

@Scope:作用域 ...

@Subcomponent:子组件...

注解还有很多,准备放到细枝篇来写了...?

实现原理

dagger编译期解析注解创建辅助类的过程就不分析了,我们直接看他生成的辅助类,

注:一开始写接口名字时,用造车图纸CarGraph而不是造车厂CarFactory,是为了避免和dagger的生成类搞混,用CarGraph有几何图的寓意,可以理解成造车蓝图(PPT),让我们一起,为梦想窒息...

我们看到DaggerCarGraph,他实现了我们的CarGraph接口,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class DaggerCarGraph implements CarGraph {
    //Provider,提供多引擎map,<引擎名字、引擎实例>
    private Provider<Map<String, IEngine>> mapOfStringAndIEngineProvider;
    //Provider,提供NewCar
    private Provider<NewCar> newCarProvider;

    private DaggerCarGraph() {
        initialize();
    }

    public static Builder builder() {
        return new Builder();
    }

    public static CarGraph create() {
        //用builder创建DaggerCarGraph实例
        return new Builder().build();
    }

    private void initialize() {
        //创建提供汽油引擎的Provider和电动引擎的Provider
        //用put将他们存起来,合并成一个提供多引擎map的Provider
        this.mapOfStringAndIEngineProvider = MapFactory.<String, IEngine>builder(2)
            .put("Gas", (Provider) GasEngine_Factory.create())
            .put("Electric", (Provider) ElectricEngine_Factory.create())
            .build();
        //把提供多引擎map的Provider传入NewCar_Factory,
        //然后用DoubleCheck包一层,他会加锁、处理单例逻辑
        this.newCarProvider = DoubleCheck.provider(
            NewCar_Factory.create(mapOfStringAndIEngineProvider));
    }

    @Override
    public Car makeCar() {
        //1. 老的造车:姿势一,用makeCar直接造
        return new Car(new Engine());
    }

    @Override
    public void inject(DaggerActivity activity) {
        //2. 老的造车:姿势二,用@Inject注入 ↓
        injectDaggerActivity(activity);
    }

    private DaggerActivity injectDaggerActivity(DaggerActivity instance) {
        //2. 老的造车:姿势二,先创建后注入
        //实例的创建也用makeCar,如果我们接口没有定义这个方法,dagger会生成一个功能一样的getCar
        DaggerActivity_MembersInjector.injectMCar(instance, makeCar());
        return instance;
    }

    @Override
    public NewCar makeNewCar() {
        //3. 新的造车,从Provider获取
        return newCarProvider.get();
    }

    public static final class Builder {
        private Builder() {
        }
        public CarGraph build() {
            return new DaggerCarGraph();
        }
    }
}

  1. 老的造车:姿势一,用makeCar直接造

在造老车Car时,姿势一是直接调接口的makeCar方法来造,实现就是简单的new出实例。

  1. 老的造车:姿势二,用@Inject注入

姿势二用@Inject注入实例,可见他也是先调makeCar()得到实例,然后调DaggerActivity_MembersInjector.injectMCar进行注入,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//DaggerActivity_MembersInjector.java
@InjectedFieldSignature("com.holiday.srccodestudy.dagger.DaggerActivity.mCar")
public static void injectMCar(DaggerActivity instance, Car mCar) {
    //引用DaggerActivity的成员,为其赋值,可见mCar不能声明为private
    instance.mCar = mCar;
}

  1. 新的造车,从Provider获取

在造新车NewCar时,是从Provider获取的,跟进newCarProvider.get(),如果使用了单例@Singleton,NewCar_Factory会被DoubleCheck包一层,DoubleCheck会加锁和处理单例逻辑,我们直接看NewCar_Factory的get就行了,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//Factory<T> extends Provider<T>
class NewCar_Factory implements Factory<NewCar> {
    private final Provider<Map<String, IEngine>> engineMapProvider;

    public NewCar_Factory(Provider<Map<String, IEngine>> engineMapProvider) {
        this.engineMapProvider = engineMapProvider;
    }

    @Override
    public NewCar get() {
        //通过engineMapProvider获取多引擎map
        return newInstance(engineMapProvider.get());
    }

    public static NewCar_Factory create(Provider<Map<String, IEngine>> engineMapProvider) {
        return new NewCar_Factory(engineMapProvider);
    }

    public static NewCar newInstance(Map<String, IEngine> engineMap) {
        //new出新车实例
        return new NewCar(engineMap);
    }
}

看下多引擎map又是如何获取的,engineMapProvider.get(),

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//MapFactory.java
//MapFactory extends AbstractMapFactory implements Factory
public Map<K, V> get() {
    //创建新的LinkedHashMap
    Map<K, V> result = newLinkedHashMapWithExpectedSize(contributingMap().size());
    //遍历已存入的引擎,存进新map
    for (Entry<K, Provider<V>> entry : contributingMap().entrySet()) {
        result.put(entry.getKey(), entry.getValue().get());
    }
    //返回不可修改的map
    return unmodifiableMap(result);
}

至此,dagger的各生产线流程就分析完了,

细枝

@Scope作用域、@Subcomponent子组件、还有SPI(Service Provider Interface)、grpc(谷歌的远程过程调用框架)等,都留到细枝篇来写啦。

使用场景

那dagger在Android中有哪些用武之地?首先是从架构角度,在谷歌示例中,结合了Activity、伪ViewModel、Repository、DataSource和Retrofit来使用dagger,(还没用过,不知道香不香、坑多不多,靠屏幕前的大佬们反馈了~)

然后我们在项目中的一些场景,是从业务角度切入,在个别复杂度较高的业务线上单独使用dagger。例如钱包业务,有大量实例大量页面/视图存在多对多关系,比如钱包Act需要钱包Api、钱包用户信息Manager;充值Act需要支付Api、充值Service;银行卡列表View需要银行Service...像这种多对多、对象依赖关系杂乱无章的场景,很适合用dagger来帮我们注入。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@PurseScope //钱包作用域
@Component(modules = PurseModule.class) //由PurseModule提供实例
public interface PurseComponent {

    //为act注入
    void inject(退款详情Act xxxAct);
    void inject(银行卡首页Act xxxAct);
    void inject(钱包首页Act xxxAct);
    void inject(钱包设置Act xxxAct);
    void inject(余额首页Act xxxAct);
    //...

    //为view注入
    void inject(钱包首页GridContainer xxxGridContainer);
    void inject(银行卡列表View xxxView);

    //提供网络调用
    支付Api xxxApi();

    //提供钱包用户信息
    钱包用户信息Manager xxxManager();

    //...
}

然后看到PurseModule,用于提供各种实例,可以new、手动单例、工厂生产...

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Module
public class PurseModule {
    @Provides
    @PurseScope
    public 支付Api provide支付Api(...) {
        return new 支付Api(...);
    }

    @Provides
    @PurseScope
    public 用户信息Manager provide用户信息Manager(...) {
        return 用户信息Manager.get(...);
    }

    @Provides
    @PurseScope
    public 充值Service provide充值Service(...) {
        return new 充值ServiceFactory.create(...);
    }

    //...
}

尾声

简单总结下dagger的优缺点~

  • 优势:无反射、支持增量编译
  • 缺点:构建过程需要而外的io和编译时间、生成类会增大包体积、不够好用、

后续计划:dagger细枝、hilt、koin、顺便看看spring上的注入@Autowired是怎么做的...学海无涯啊~

系列文章:

  • 《看完不忘系列》之Retrofit
  • 《看完不忘系列》之okhttp
  • 《看完不忘系列》之Glide

参考资料


欢迎关注原创技术公众号:哈利迪ei

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 哈利迪ei 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android | dagger细枝篇
嗨,我是哈利迪~《看完不忘系列》之dagger(树干篇)一文对dagger做了初步介绍,下面我们一起来瞅瞅dagger的一些细节。
Holiday
2020/09/03
8330
Android | dagger细枝篇
Dagger2神器入门(二)
在Dagger2神器入门(一)中,我们了解了什么是依赖注入,那么在这一章中,我们将逐渐入门Dagger2。接下来我们会通过demo形式给大家展现Dagger2的神奇之处。
用户2802329
2018/08/07
4500
Android Hilt实战初体验: Dagger替换成Hilt
在组件化AwesomeGithub项目中使用了Dagger来减少手动依赖注入代码。虽然它能自动化帮我们管理依赖项,但是写过之后的应该都会体会到它还是有点繁琐的。项目中到处充斥着Component,这让我想起了传统MVP模式的接口定义。
Rouse
2020/07/21
2K0
Jetpack新成员,一篇文章带你玩转Hilt和依赖注入
虽然今年的Google I/O大会由于疫情的原因没能开成,但是Google每年要发布的各种新技术可一样都没少。
用户1158055
2020/11/26
2.8K0
Jetpack新成员,一篇文章带你玩转Hilt和依赖注入
Dagger Android支持库(译文)
与其他依赖注入框架相比,Dagger 2 最大的优点是他不使用反射,严格的生成实现类,这意味着他可以使用在 Android 应用上。但是在Android上使用仍有一些注意事项。
haifeiWu
2018/09/11
1.1K0
Android注解三大框架Dagger、Hilt 和 Koin 有何不同?
Dagger 和 Koin 无疑是 Android 中最流行的两个依赖注入框架。这两个库具有相同的用途,而且看起来非常相似,但它们在底层的工作方式却非常不同。
用户9239674
2021/12/21
2.7K0
带你解析Dagger2
Dagger2是Dagger1的分支,由谷歌公司接手开发,目前的版本是2.0。Dagger2是受到AutoValue项目的启发。 刚开始,Dagger2解决问题的基本思想是:利用生成和写的代码混合达到看似所有的产生和提供依赖的代码都是手写的样子。
老马的编程之旅
2022/06/22
9010
Android--Hilt入门
和Dagger相同,Hilt也分两种注入方式,以上篇Dagger中的代码为例子,来对比两个框架的使用区别
aruba
2021/12/16
1.6K0
Android--Hilt入门
了不起的 IoC 与 DI
本文阿宝哥将从六个方面入手,全方位带你一起探索面向对象编程中 IoC(控制反转)和 DI(依赖注入) 的设计思想。阅读完本文,你将了解以下内容:
阿宝哥
2020/08/19
3K0
Dagger2从懵懂到精通,在线学习那点事儿
现在Dagger2在项目里用的越来越多了,最近花了些时间学习了一下Dagger2,这篇文章主要帮助理解Dagger2的注入实现过程,如有错误,还请指正!
java爱好者
2019/07/07
7410
带你了解Android Jetpack库中的依赖注入框架:Hilt
Hilt是Google推出的一种用于Android的依赖注入(Dependency Injection,DI)框架,构建于Dagger之上,旨在简化Android应用中的依赖注入过程。通过Hilt,你可以更轻松地管理和提供依赖,显著减少DI的样板代码,并提高应用的可测试性和可维护性。
AntDream
2024/09/13
5570
带你了解Android Jetpack库中的依赖注入框架:Hilt
从 Dagger 迁移到 Hilt 可带来的收益
Hilt 发布于 2020 年 6 月,为 Android 提供了依赖项注入 (DI) 的标准化方案。对于新项目,Hilt 有着编译期校验,良好的运行时性能以及扩展性 (阅读文章 Android 和 Hilt 中限定作用域,获取更多信息)。然而,Hilt 对于已经使用 Dagger 的应用有何优势呢?您是否应该将现有的应用迁移到 Hilt 呢?以下几点阐述了您的团队需要投入精力到迁移工作中的原因。
Android 开发者
2022/03/09
9460
Kotlin 中使用 Hilt 的开发实践
Hilt 是基于 Dagger 开发的全新的依赖项注入代码库,它简化了 Android 应用中 Dagger 的调用方式。本文通过简短的代码片段为您展示其核心功能以帮助开发者们快速入门 Hilt。
Android 开发者
2022/03/09
1.3K0
Android 面试题:为什么 Activity 都重建了 ViewModel 还存在?—— Jetpack 系列(3)
ViewModel 是 Jetpack 组件中较常用的组件之一,也是实现 MVVM 模式或 MVI 模式的标准组件之一。在这篇文章里,我将与你讨论 ViewModel 实用和面试常见的知识点。如果能帮上忙请务必点赞加关注,这对我非常重要。
用户9995743
2022/09/26
1.4K0
Android 面试题:为什么 Activity 都重建了 ViewModel 还存在?—— Jetpack 系列(3)
Dagger2神器入门
网上随便搜索一下Dragger2,一大堆文章铺天盖地而来,一上来就讲@Inject,@Module等注解是做什么的,解释一大堆,看完之后一脸懵逼。对于刚刚入门Dagger的同学们来讲,这样的文章只会让你觉得生无可恋,看完之后还是不知道怎么使用?
用户2802329
2018/08/07
4640
Andriod-Dagger2
参考资料: https://www.jianshu.com/p/1d84ba23f4d2 https://mp.weixin.qq.com/s/lh3dgJK95cgbG-bUZfvbFA
android_薛之涛
2019/08/18
2.4K0
Angular 依赖注入简介
在介绍依赖注入的概念和作用前,我们先来看个例子。各位同学请睁大眼睛,我要开始 “闭门造车” 了。
阿宝哥
2019/11/05
8250
Dagger2 入门解析
前言 在为dropwizard选择DI框架的时候考虑了很久。Guice比较成熟,Dagger2主要用于Android。虽然都是google维护的,但Dagger2远比guice更新的频率高。再一个是,Dagger2不同于guice的运行时注入,编译时生成代码的做法很好。提前发现问题,更高的效率。 还是那句话,百度到的dagger2资料看着一大堆,大都表层,而且和Android集成很深。很少有单独讲Dagger2的。不得已,去看官方文档。 HelloWorld 官方的example是基于maven的,由于
Ryan-Miao
2018/03/14
1.6K0
Dagger2的轻松愉悦解析
  Dagger2,依赖注入框架,一个刚接触时感觉麻烦,用久了就会“嘴上说不要,身体却很诚实”的开发润滑剂(◐‿◑)。(本文为拖更而生)
GSYTech
2018/08/22
5880
Dagger2的轻松愉悦解析
Android--Dagger2入门
在moudle的gradle中做如下配置,我在2.30.1版本中尝试使用构造函数注入,发现怎么编译都会报错,结果最后使用最新版本就可以了:
aruba
2021/12/06
7510
Android--Dagger2入门
相关推荐
Android | dagger细枝篇
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档