告别Dagger2模板代码:Dagger Android使用详解

android Dagger2简单使用 这个是简单的使用Dagger2的Demo,里面使用很简单,但是还是建议大家能回注解这种代码,不然也很难看懂 立即下载

概述,学Dagger2-Android的理由

Dagger2的窘境

在使用Dagger2进行Android开发时,不可避免的问题是我们需要实例化一些Android系统的类,比如Activity或者Fragment。最理想的情况是Dagger能够创建所有需要依赖注入的对象,但事实上,我们不得不在容器的声明周期中声明这样的代码:

public class FrombulationActivity extends Activity {
  @Inject Frombulator frombulator;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // DO THIS FIRST. Otherwise frombulator might be null!
    ((SomeApplicationBaseType) getContext().getApplicationContext())
        .getApplicationComponent()
        .newActivityComponentBuilder()
        .activity(this)
        .build()
        .inject(this);
    // ... now you can write the exciting code
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这样的确可以实现Android的依赖注入,但还有两个问题需要我们去面对:

1.即使Dagger使我们的代码耦合性更低,但是如果要面临重构,我们仍然不得不去面对每个Activity中这样数行需要我们「复制」+「粘贴」的代码,这会给我们的重构带来一定的难度(试想一下,如果我们的应用有数十个乃至上百个这样的Activity或者Fragment容器,我们的重构计划,首先就要面对这样数百行的代码)。 
并且随着新的开发人员加入(他们也许并不知道这些代码的意义,但是他们会复制粘贴),越来越少的人知道这些代码都干了些什么。 
2.更重要的是,它要求注射类型(FrombulationActivity)知道其注射器。 即使这是通过接口而不是具体类型完成的,它打破了依赖注入的核心原则:一个类不应该知道如何实现依赖注入。

瑕不掩瑜!

诚如标题所言,虽然Dagger2在Android开发中有一些问题,但是它强大的功能依然使得开发人员趋之若鹜,无数的工程师们尝试弥补Dagger的这个问题,于是Dagger2-Android,基于Dagger2,应用于Android开发,由google开发的的拓展库应运而生。

本文结构

  1. 概述,我们学Dagger2-Android的理由
  2. 应用,Dagger2-Android入门Demo
  3. 重构,基于google官方demo的优化尝试
  4. 源码分析,知其然亦要知其所以然
  5. 总结
「提示」本文篇幅较长,且和Dagger2的使用有一定的区别(需要额外的学习成本),若您觉得本文尚可,建议收藏慢慢阅读
「知识储备」本文可能需要您对Dagger2有足够的了解

如果您对Dagger2一些知识点不熟悉,可以尝试看一下笔者的Dagger2相关文章:

Dagger2使用详解(四)Scope注解的使用及源码分析

Dagger2使用详解(三)进阶篇 MVP架构下的使用

Dagger2使用详解(二)Module&Component源码分析

Dagger2使用详解(一)基础使用

应用,Dagger2-Android入门Demo

1.环境&依赖

    annotationProcessor 'com.google.dagger:dagger-compiler:2.11' //一定要添加dagger2的annotationProcessor!
    compile 'com.google.dagger:dagger-android:2.11'
    compile 'com.google.dagger:dagger-android-support:2.11' // if you use the support libraries
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.11
  • 1
  • 2
  • 3
  • 4
  • 5

2.Demo结构分析

首先我们先看看Demo效果

这里写图片描述

结构如下:

这里写图片描述

可以看到,我们在MainActivity中需要通过依赖注入,获得4个对象,同时MainPresenter和MainModel也同样得到了实例化,我们先看下MVP这个架构中三个成员的代码:

3.MVP基本代码

MainActivity相关代码

MainActivity代码:

public class MainActivity extends BaseActivity implements MainContract.View {

    @Inject
    String className;
    @Inject
    Student student;
    @Inject
    SharedPreferences sp;
    @Inject
    MainPresenter presenter;

    @BindView(R.id.tv_content)
    TextView tvContent;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        //下面这行代码把所有实例化的对象展示在界面中
        tvContent.setText(className + "\n" +
                student.toString() + "\n" +
                sp.toString() + "\n" +
                presenter.toString());
    }

     //省略其他代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

显然,从结果来看,我们根本没有在Activity中添加上文所述的模板代码:

    //就是这些,模板代码
    ((SomeApplicationBaseType) getContext().getApplicationContext())
        .getApplicationComponent()
        .newActivityComponentBuilder()
        .activity(this)
        .build()
        .inject(this);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

MainPresenter代码:

public class MainPresenter implements MainContract.Presenter {

    private final MainActivity view;
    private final MainModel model;

    @Inject
    public MainPresenter(MainActivity view, MainModel model) {
        this.view = view;
        this.model = model;
    }

    //省略其他代码
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

MainModel代码:

public class MainModel implements MainContract.Model {

    @Inject
    public MainModel() {
    }

   //省略其他代码
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

和Dagger2的使用没有区别,其根本原理,都是通过@Inject注解,使Dagger2自动生成对应的工厂类,以提供MainPresenter和MainModel的实例。

SecondActivity代码

和MainActivity基本一样,为了简便我们只注入了一个String,用来展示类名(请参照上面的gif图):

public class SecondActivity extends BaseActivity {

    @Inject
    String className;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        TextView tv = (TextView) findViewById(R.id.tv_content);
        tv.setText(className);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

可以看到,我们依然没有添加冗余的模板代码,试想,一个app中这样几十个Activity容器都不需要这样的模板代码,我们的工作量确实减少了很多,同时,也达到了我们的目的,即:

依赖注入的核心原则:一个类不应该知道如何实现依赖注入。

实际上,我们只是在BaseActivity中,添加了这样一行代码,就实现了我们想要的效果

public class BaseActivity extends AppCompatActivity{

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        AndroidInjection.inject(this);  //一处声明,处处依赖注入
        super.onCreate(savedInstanceState);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
接下来,让我们看看Dagger2-Android 的Module和Component怎么写

参考:谷歌官方Demo https://google.github.io/dagger//android.html

4.Module和Component

首先我们先声明对应Activity的Module和Component:

MainActivity依赖配置

我们声明Subcomponent,其关联的module可以提供MainActivity所需要的所有依赖的实例。

@Subcomponent(modules = {
        AndroidInjectionModule.class,
        MainActivitySubcomponent.SubModule.class
})
public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> {

    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {
    }

    @Module
    class SubModule {

        @Provides
        String provideName() {
            return MainActivity.class.getName();
        }

        @Provides
        Student provideStudent() {
            return new Student();
        }

        @Provides
        SharedPreferences provideSp(MainActivity activity) {
            return activity.getSharedPreferences("def", Context.MODE_PRIVATE);
        }

        @Provides
        MainModel provideModel() {
            return new MainModel();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

然后我们创建MainActivityModule

@Module(subcomponents = MainActivitySubcomponent.class)
public abstract class MainActivityModule {

    @Binds
    @IntoMap
    @ActivityKey(MainActivity.class)
    abstract AndroidInjector.Factory<? extends Activity>
    bindMainActivityInjectorFactory(MainActivitySubcomponent.Builder builder);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

ok,这样MainActivity的相关依赖注入配置完毕。

SecondActivity依赖配置

同理,Subcomponent代码如下:

@Subcomponent(modules = {
        SecondActivitySubcomponent.SubModule.class,
        AndroidInjectionModule.class,
})
public interface SecondActivitySubcomponent extends AndroidInjector<SecondActivity> {

    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<SecondActivity> {
    }

    @Module
    class SubModule {
        @Provides
        String provideName() {
            return SecondActivity.class.getName();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

然后是Model

@Module(subcomponents = SecondActivitySubcomponent.class)
public abstract class SecondActivityModule {

    @Binds
    @IntoMap
    @ActivityKey(SecondActivity.class)
    abstract AndroidInjector.Factory<? extends Activity>
    bindSecondActivityInjectorFactory(SecondActivitySubcomponent.Builder builder);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

各个模块配置完毕,接下来我们将上述的Module组合起来即可:

全局依赖配置

我们先声明我们的Application类,然后一定要记得添加到清单文件中:

public class MyApplication extends Application implements HasActivityInjector {

    @Inject
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();
        //DaggerMyAppComponent.create().inject(this);
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingAndroidInjector;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

请注意,我们在这里做了几件事:

1.实现HasActivityInjector接口

2.实现HasActivityInjector接口的activityInjector()方法

3.声明一个泛型为Activity的DispatchingAndroidInjector成员变量并在activityInjector()方法中返回

这里我们注释掉了一行代码,因为我们要先写AppComponent接口,然后编译,才能让编译器自动生成DaggerMyAppComponent类。

@Component(modules = {
        AndroidInjectionModule.class,
        AndroidSupportInjectionModule.class,
        MainActivityModule.class,
        SecondActivityModule.class
})
public interface MyAppComponent {

   void inject(MyApplication application);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

请注意,我们在这里做了几件事:

1.在这个Component中添加了 AndroidInjectionModule 和 AndroidSupportInjectionModule

2.同时添加了MainActivityModule 和 SecondActivityModule的依赖

3.声明注入方法inject,参数类型为MyApplication

好的,所有配置全部结束,我们使用ctrl+F9(Mac:cmd+F9)进行编译,然后打开MyApplication中注释的那行代码,运行app,依赖注入成功,如上文gif图所示。

5.除Activity之外,Dagger-Android还提供了Fragment,BroadCast,Service等其他组件的注入方式,详情请参照官方网站,本文不赘述。

https://google.github.io/dagger//android.html

6.注意

如果您按照本文中的代码实现,并没有得到对应的效果或者编译错误,请仔细检查是否严格按照本文的步骤进行编码,如果还有问题,建议您直接拉到本文最下方,下载源码查看。

重构,基于google官方demo的优化尝试

1.还有一些冗余代码

上述章节中的使用方式基本是按照谷歌官方的guide进行的依赖注入,实际上个人认为还有几点可以优化:

1.多余的ActivityModule

请参照上文的MainActivityModule和SecondActivityModule,实际上从根本上来说,也类似模板代码,当界面多了,会生成大量的java文件

2.多余的Subcomponent 
同理,太多了。

3.越来越庞大的AppComponent 
当Activity越来越多,AppComponet中的注解会变成这样:

@Component(modules = {
        AndroidInjectionModule.class,
        AndroidSupportInjectionModule.class,
        MainActivityModule.class,
        SecondActivityModule.class
        ...
        ...//中间省略不知道多少行
        XXActivityModule.class
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我们来看看目前的结构: 
这里写图片描述

可以看到,很冗余,实质上,表面上的注入器(Appcomponent),和对象的提供者(MainSubComponent.SubModule)两者起到了至关重要的作用,而Module和SubComponent作用不大。

2.假设

于是我们联想,我们可不可以改变结构成这样呢:

这里写图片描述

简述如下:

1.AppComponent的module:AllActivityModule,其负责所有ActivityModule实例的管理

2.BaseActivityComponent为AllActivityModule的subcomponent,管理了提供各activity所需对象的module

3.MainActivityModule 负责提供所有对应Activity所需要对象实例的提供。

3.实装

首先,创建BaseActivityComponent,并将所有的ActivitySubcomponent删除:
@Subcomponent(modules = {
        AndroidInjectionModule.class,
})
public interface BaseActivityComponent extends AndroidInjector<BaseActivity> {
    //每一个继承BaseActivity的Activity,都共享同一个SubComponent
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<BaseActivity> {
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
然后我们将对应的对象提供放到ActivityModule里:

MainActivityModule:

@Module
public class MainActivityModule {

    @Provides
    static String provideName() {
        return MainActivity.class.getName();
    }

    @Provides
    static SharedPreferences provideSp(MainActivity activity) {
        return activity.getSharedPreferences("def", Context.MODE_PRIVATE);
    }
    //其他对象的提供 省略
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

SecondActivityModule:

@Module
public abstract class SecondActivityModule {

    @Provides
    static String provideName() {
        return SecondActivity.class.getName();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

那么问题来了,我们原本放在这里面的这些代码怎么办呢,例如:

    @Binds
    @IntoMap
    @ActivityKey(SecondActivity.class)
    abstract AndroidInjector.Factory<? extends Activity>
    bindSecondActivityInjectorFactory(SecondActivitySubcomponent.Builder builder);
  • 1
  • 2
  • 3
  • 4
  • 5
新建AllActivitysModule,并统统放入其中统一管理:
@Module(subcomponents = {
        BaseActivityComponent.class
})
public abstract class AllActivitysModule {

    @ContributesAndroidInjector(modules = MainActivityModule.class)
    abstract MainActivity contributeMainActivitytInjector();

    @ContributesAndroidInjector(modules = SecondActivityModule.class)
    abstract SecondActivity contributeSecondActivityInjector();

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这样,我们每次新建一个Activity,只需要统一在这里新建2行代码声明对应的Activity即可。

对个人而言,这样的好处在于: 
1.每次不再需要额外声明一个SubCompoent,再次减少模板代码 
2.每个Activity的Module都放在同一个AllActivitysModule中进行统一管理,每次修改只需要修改这一个类即可 
3.每个Activity所单独需要的依赖,依然由各自的Module进行管理和实例化,依然没有任何耦合

关于这两行代码的解释,请参考官网:https://google.github.io/dagger//android.html

Pro-tip: If your subcomponent and its builder have no other methods or supertypes than the ones mentioned in step #2, you can use @ContributesAndroidInjector to generate them for you. Instead of steps 2 and 3, add an abstract module method that returns your activity, annotate it with @ContributesAndroidInjector, and specify the modules you want to install into the subcomponent. If the subcomponent needs scopes, apply the scope annotations to the method as well.

@ActivityScope 
@ContributesAndroidInjector(modules = { /* modules to install into the subcomponent */ }) 
abstract YourActivity contributeYourActivityInjector();

最后修改AppComponent
@Component(modules = {
        AndroidInjectionModule.class,
        AndroidSupportInjectionModule.class,
        AllActivitysModule.class    
})
public interface MyAppComponent {

    void inject(MyApplication application);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
修改完毕,大功告成!

好的,所有配置全部结束,我们使用ctrl+F9(Mac:cmd+F9)进行编译,然后打开MyApplication中注释的那行代码,运行app,依赖注入依旧成功。

不同的是,这次我们的模板代码更少了。

源码分析,知其然亦要知其所以然

一路写下来,单单该库的使用,竟然洋洋洒洒竟然写了这么多,实在超出预料。

// 源码分析,鉴于篇幅所限,准备另起一篇文章改日慢慢分析。 2017/8/22

2017/8/30更新

源码分析,鉴于篇幅所限,另起一篇文章,请阅读本文:

Dagger-Android详解&源码分析

总结

看了这么多,有的朋友可能会看了几眼就不看了,也一定会有人觉得笔者啰嗦,文笔有限,但还是希望能够给大家提供一定的帮助,毕竟关于这个库,国内的中文相关资料实在有限,而Dagger依赖注入库的学习成本,也是出了名的高。

最后提供一下本文demo源码连接:

https://github.com/qingmei2/Sample_dagger2

Android视频教程Dagger2 1.为什么要使用Dagger2.mp4 2.Dagger2的基本使用.mp4 3.模块化实现.mp4 4.创建和区分不同实例.mp4 5.Singleton 单例讲解.mp4 6.自定义Scope.mp4 7.SubCompnet和Lazy与Provider.mp4 立即下载

相关推荐

Android-Jet使用注解功能来实现去除一些重复的模板代码

标签注解库 ,自动初始化 类的Field 属性和自动初始化Intent;Field and method binding for Android views

android dagger2官网,Android Dagger2 从零单排(四) Dependencies与SubComponent

上一篇我们详细介绍了作用域@Scope的使用,本篇我们来研究Dependencies与SubComponent的用法。在前几篇的例子里,@Component都是跟@Module一一对应的提供依赖,如果一个@Component需要用另一个@Component提供依赖,这种情况该如何处理?比如,在Activity注入的依赖,依赖于Applicaton维护的全局单例对象,可能会第一时间想到,先用全局@C...

weixin_42629815的博客 277

dagger2使用方法教程之简明讲解

Dagger2 是一个Android依赖注入框架,由谷歌开发,最早的版本Dagger1 由Square公司开发。下面这篇文章主要给大家介绍了关于dagger2的一些使用方法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。

使用Dagger2 对第三方依赖库进行初始化,减少Application 代码的冗余

作用:对于在 Application 中进行初始化(如第三方依赖库) 使用 Dagger 进行包装处理,减少Application 代码的冗余。 原理 :将每个依赖的初始化算法包装到它自己的类中,向Dagger发信号通知我们要将它们绑定到一个集合中,然后迭代它并告诉每个依赖执行它的初始化。 实现步骤: 1. 定义一个Initializer 接口,每个依赖初始化包装器(TimberIn...

无常的专栏 579

什么是深度展开网络?如何将迭代算法的每一次迭代展开成深度网络对应的一层?深度展开网络进行端对端训练,其中端对端是什么意思?

在深度学习和机器学习的背景下,“端到端”(End-to-end)训练指的是将输入数据直接映射到最终输出的过程,而不需要任何中间的手动数据预处理或特征工程。- **自然语言处理**:端到端自然语言处理系统可以将自然语言输入直接转化为计算机可理解的语言输出,而不需要对语言进行分解和转化。- **推荐系统**:通过使用深度神经网络,端到端推荐系统可以直接根据用户历史行为预测其未来的兴趣爱好,并推荐相应的产品或服务。4. **直接映射**:从输入到输出的直接映射,中间没有任何拆分或分解的过程。

m0_67897882的博客 5436

MySQL 8.0数据库崩了别慌!手把手教你仅凭一个.ibd文件找回数据(附Go工具包)

本文详细介绍了在MySQL 8.0数据库崩溃后,如何仅凭.ibd文件恢复数据的完整流程。通过使用Go语言工具包和ALTER TABLE技巧,即使没有备份也能实现数据重生。文章包含从环境准备到数据验证的全方位指导,帮助DBA和开发者应对紧急数据恢复场景。

weixin_29235923的博客 420

dagger android,Dagger2 系列(三)Dagger2.Android使用详解

前言前两篇文章我们介绍了dagger2的使用和基本原理,为了适用于android项目代码特点,更简洁的实现四大组件和Fragment的注入,dagger2团队为我们又进一步的封装,也就是我们要介绍的dagger2.android。对dagger2原理和使用不了解的朋友先移步看前两篇文章。dagger2.android 产生的意义上篇文章讲到了component的继承和依赖实现方式,在实际andro...

weixin_30104235的博客 447

海康工业相机使用:常见问题及解决方法

工业相机在使用过程中,经常会因为操作不当、使用环境不当等原因出现一些问题,本篇教程,主要针对海康工业相机常见问题及其定位方法做以简单介绍,希望可以帮助大家。 注:该教程对其他品牌工业相机“常见问题”排查,也具备一定的指导意义。 当出现无法通过客户端发现设备或者无法预览图像等问题,先确认当前的运行环境是否满足以下要求: 确认装有相机驱动软件的电脑网卡为千兆网卡(Gige接口相机); 确认网卡是否已开启巨型帧; 确认电脑与网口相机之间的网络链路为千兆; 确认装有相机驱动软件的USB接口为3...

Cche的博客 3万+

Dagger2 @Component 和@SubComponent 区别解惑

前言当前很多blog和技术网站,很多文章都在讲Dagger2 的使用,一般都是在Application中生成一个AppComponent,然后其他的功能模块的Component依赖于AppComponent,但是有些文章中使用的方式是@Component(modules = PreseterModule.class, dependencies = AppComponent.class),也有使用@S

Lincoln 的专栏 1万+

BioEmu:微软黑科技炸场!生成式AI重构蛋白质模拟:千倍效率碾压传统计算,新药研发周期砍半

BioEmu 是微软推出的生成式深度学习系统,可在单个 GPU 上每小时生成数千种蛋白质结构样本,支持模拟动态变化、预测热力学性质,并显著降低计算成本。

士多啤梨先生の博客 1100

家庭路由器从入门到精通:连接设置、优化排障全指南

路由器作为家庭网络的核心枢纽,其工作原理基于NAT(网络地址转换)和DHCP(动态主机配置协议)两大关键技术。NAT负责将公网IP转换为多个内网IP,实现多设备共享上网;DHCP则自动为接入设备分配IP地址,简化网络配置。这些技术共同构建了稳定、安全的局域网环境,其价值在于为智能家居、在线办公、高清影音和游戏娱乐等场景提供可靠的网络基础。理解路由器的物理连接、后台设置与故障排查逻辑,是优化Wi-Fi信号覆盖、提升网络性能、保障家庭网络安全的关键。本文以路由器配置与排障为核心,详细解析从WAN/LAN口区分、

weixin_33393017的博客 406

android dagger2 讲解,告别Dagger2模板代码:DaggerAndroid原理解析

本系列所有文章:概述距离我的上一篇文章发布以来,有幸收获了一些朋友的认可,我很开心。在上一篇文章中,我简单叙述了Dagger2这个库目前在Android开发中的一些短板,为什么我们学习Dagger-Android这个拓展库,以及如何使用这个拓展库。今天我们进行代码分析,看看Dagger-Android是如何基于Dagger2实现一行代码实现所有同类组件依赖注入的。阅读本文也许您需要准备的本文可能需...

weixin_31289551的博客 414

C#单例模式在工控上位机的实战应用:一台设备只连一次,稳定运行7×24小时

在工控行业,稳定性比功能更重要。一台上位机需要7×24小时运行,任何一次因资源冲突导致的停机,都可能给工厂带来巨大损失。单例模式的核心价值,就是通过保证资源唯一性,避免PLC连接冲突、串口占用、日志写入错乱等问题,为工控上位机的稳定运行保驾护航。按需使用:不是所有类都要单例,只有资源唯一性的类才用;线程安全:多线程场景下,必须用双重检查锁定或静态内部类写法;手动释放:单例类中的硬件资源(PLC、串口),程序退出时必须手动释放,避免资源泄漏。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 550

告别模板代码:Dagger Android扩展与Hilt集成新范式

你是否还在为Android依赖注入编写大量模板代码?从手动创建Component到管理生命周期,这些重复劳动不仅耗费时间,还容易出错。本文将带你一文掌握Dagger Android扩展与Hilt的无缝集成,通过实战案例展示如何减少80%模板代码,让依赖注入变得简单高效。读完本文,你将学会:Hilt的核心优势、从Dagger迁移的平滑路径、以及在真实项目中落地的最佳实践。 ## Dagger An...

gitblog_00731的博客 376

PCB_Project.PrjPcb 4 Not in version control

Altium Designer中PCB项目出现"NOT in version control"错误的解决方法:1. 禁用不需要的版本控制集成(DXP→Preferences→Version Control);2. 清理项目缓存(Projects面板右键→Clean Project);3. 检查文件读写权限;4. 如无效可新建项目重新添加文件。如需使用SVN版本控制,需正确配置SVN客户端路径,创建或连接SVN仓库,并将项目文件提交至版本控制系统。注意新建SVN仓库必须使用空目录,建议使用

whm128的博客 1599

【11】GD32H7xx MPU记录

GD32H7xx系列MPU内存保护单元模块的使用记录

madao1234的博客 878

告别Dagger2模板代码:DaggerAndroid原理解析

概述距离我的上一篇文章打破Dagger2使用窘境:Dagger-Android使用详解发布以来,有幸收获了一些朋友的认可,我很开心。在上一篇文章中,我简单叙述了Dagger2这个库目前在Android开发中的一些短板,为什么我们学习Dagger-Android这个拓展库,以及如何使用这个拓展库。今天我们进行代码分析,看看Dagger-Android是如何基于Dagger2实现一行代码实现所有同类组件

却把清梅嗅的博客 6877

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

一文看懂 Android Studio MVP 模板三大功能:Boilerplate、Activity、Fragment 详解

Android Studio MVP 模板(Android-Studio-MVP-template)是一款为 Android 开发者打造的免费 MVP 架构代码生成工具。它通过 3 个内置模板——MVP Boilerplate、MVP Activity 和 MVP Fragment——一键生成规范的 MVP 工程结构与页面代码,让你彻底告别手写重复样板代码,快速搭建结构清晰、Presenter 可

gitblog_01124的博客 863

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Crossplane Packages v2 设计全解:Package / PackageRevision / PackageLock 三级包管理架构与升级机制

本文深度解读 Crossplane 官方设计文档《Packages v2》([design/design-doc-packages-v2.md](https://link.gitcode.com/i/f9b8afb67c1057f824f3517a8c26338e)),围绕"以声明式 Package 统一包安装单元、以 PackageRevision 支持版本升级、以 PackageLock 支撑

gitblog_00899的博客 752

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

告别Dagger2,Android的Kotlin项目中使用Kodein进行依赖注入

前言:依赖注入浅谈 Dagger2的困境 对于依赖注入(Dependency Injection,简称DI)来讲,它并非是一个新鲜的词汇,实际上,它很早就被提出并且应用在了企业级的web应用开发当中,比如Spring。 在Android开发领域内,毫无疑问,Google大名鼎鼎的 Dagger2 是依赖注入框架的首选工具库,它非常优秀,Github上数以万计的star是最强力的佐证,...

却把清梅嗅的博客 4873

MVP 模式深度解析:View、Presenter、Interactor 在 Android Studio MVP 模板中如何分工协作

**Android Studio MVP 模板**是一款专为 Android Studio 打造的 MVP 模式(Model-View-Presenter)代码模板,它能让新手一键生成结构规范的 View、Presenter、Interactor 三层代码,从此告别手写样板代码。本文将深入剖析这三个角色在模板中如何分工协作,并教你快速上手这套模板。 ## 一、为什么需要 Android Stud

gitblog_01048的博客 668

Android开发从Dagger2迁移至Kodein的感受

原文:From Dagger2 to Kodein: A small experiment 作者:Allan Yoshio Hasegawa 译者:却把清梅嗅 译者说 我是却把清梅嗅,一个普通的Android开发者。去年,我写了一系列关于Android开发者依赖注入框架 Dagger2 及 dagger.android 的博客: Android 神兵利器Da...

却把清梅嗅的博客 2512

Vite 配置文件报 This package is ESM only 怎么解决?

运行 `vite` 启动开发服务器或 `vite build` 构建时,如果配置文件里引入的某个依赖是 ESM only 包,而配置本身被 Node.js 当作 CommonJS 加载,就会在加载配置阶段失败。Vite 官方 troubleshooting 文档给出了两种报错形态(下面是文档中的示例文本,`"foo"` 和路径在你的实际报错里会替换成真实的依赖名与文件路径): ``` Faile

gitblog_01061的博客 1136

探索MVPArms的魅力:一键构建高效安卓开发框架

探索MVPArms的魅力:一键构建高效安卓开发框架 在这个快速迭代的时代,开发者们对于提升工作效率的追求从未停止。MVPArms项目,由JessYanCoding倾力打造,旨在简化复杂性,让你告别繁琐的项目配置过程,轻松步入高效开发的世界。 项目介绍 MVPArms是一个专为安卓应用程序设计的强大模板系统,它提供了一套完善的架构支持,包括MVP模式、Dagger2依赖注入、Retrofit数据请求...

gitblog_00833的博客 823
上一篇: 那些年收藏的Android开源库集合(UI效果)
下一篇: Android Dagger2 MVP架构 一看就明白
candyguy242
博客等级 码龄17年 63粉丝 37原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值