美文网首页
关于MVP+Dagger2的一些知识

关于MVP+Dagger2的一些知识

作者: 勤息嘻嘻嘻 | 来源:发表于2018-04-17 17:06 被阅读22次

    原文地址:https://www.jianshu.com/p/01d3c014b0b1

    看了大神Android-从零开始搭建android框架系列 前几章还比较清晰 到了dagger2发现了dagger2的优点 但是+mvp就不是特别理解如何在项目中运用。

    文章评论中推荐了另一个作者的文章

    地址 :https://www.jianshu.com/p/65737ac39c44

    需要找时间把这三篇文章看明白 然后再修改mvp模式的demo

    笔记1.
    依赖注入(Dependency Injection简称DI)
    java中 注解(Annotation)

    Inject
    优点:取消new对象通过 注入 获取实例
    注解(Annotation)来标注目标类中所依赖的其他类,同样用注解来标注所依赖的其他类的构造函数,那注解的名字就叫Inject

    Component
    一个连接两个类的桥梁
    需要引用到目标类的实例,查找用Inject注解标注的属性,与对应的构造函数并赋值,Component也叫注入器(Injector)

    Module
    封装第三方类库使用,简单的工厂模式。

    Component中的modules属性可以把Module加入Component,modules可以加入多个Module。

    Provides
    Module中的创建类实例方法用Provides进行标注,Component在搜索到目标类中用Inject注解标注的属性后,Component就会去Module中去查找用Provides标注的对应的创建类实例方法,这样就可以解决第三方类库用dagger2实现依赖注入了。

    笔记2

    Qualifier(限定符)
    通过Inject创建实体类和通过Module创建实体类创建一个类时,依赖注入迷失,用限定符对不同创建实例方法标识,对目标类响应的实例属性进行标注,能解决问题。

    Scope(作用域)
    通过自定义Scope注解可以更好的管理创建的类实例的生命周期。

    划分Component有两种,一种针对全局,最终针对activity或者fragment

    Singleton
    (在Module中定义创建全局类实例的方法
    ApplicationComponent管理Module
    保证ApplicationComponent只有一个实例)
    更好的管理ApplicationComponent和Module之间的关系,保证ApplicationComponent和Module是匹配的。若ApplicationComponent和Module的Scope是不一样的,则在编译时报错。

    组织Component
    类实例共享三种方式
    依赖方式:Component中的dependencies属性
    包含方式:SubComponent就是包含方式的具体实现
    继承方式:把一些Component共有的方法抽象到一个父类中,然后子Component继承

    Scope
    更好的管理Component之间的组织方式,更好的管理Component与Module之间的匹配关系,可读性提高,如用Singleton标注全局类,这样让程序猿立马就能明白这类是全局单例类。

    笔记3

    dagger2的好处
    增加开发效率,省去重复的简单体力劳动。
    更好的管理类实例。
    解耦

    步骤1:查找Module中是否存在创建该类的方法。
    步骤2:若存在创建类方法,查看该方法是否存在参数
    步骤2.1:若存在参数,则按从**步骤1**开始依次初始化每个参数
    步骤2.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
    步骤3:若不存在创建类方法,则查找Inject注解的构造函数,
           看构造函数是否存在参数
    步骤3.1:若存在参数,则从**步骤1**开始依次初始化每个参数
    步骤3.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
    

    `

    注意事项
    1.一个app必须要有一个Component(名字可以是ApplicationComponent)用来管理app的整个全局类实例
    2.多个页面可以共享一个Component
    3.不是说Component就一定要对应一个或多个Module,Component也可以不包含Module
    4.自定义Scope注解最好使用上,虽然不使用也是可以让项目运行起来的,但是加上好处多多。

    接下来分析一下大神的Demo

    原地址:https://github.com/niuxiaowei/Dagger2Sample

    首先看一下项目结构


    结构1.png 结构2.png

    这里边有个有趣的事情
    App这个类中DaggerAppComponent 是报错的 没有找到这类,但是项目编译后已经导入不报错了,点开文件发现文件在debug文件夹内


    结构3.png

    这个文件位置在上边,这种情况我是没有用到过的,发现这个类被 @Generated 标记了,也许和这个标注有关。

    Demo运行起来很简单 两个按钮 一个获取用户信息,一个点击显示toast

    首先分析一下data包
    GetUserData构造方法被 @Inject标注了,其中还有getUser()方法,返回的是一个UserData的实例,name属性有值。
    UserData是一个实体类只有一个name属性。

    di包就是dagger2用到相关的类

    components包连接两个类的桥梁
    ActivityComponent 是同时被Component和scopes.PerActivity标注的里边有一个getActivity()方法。
    AppComponent有两个标记@Singleton是单例的意思,@Component是连接器的意思,里边有3个方法,获取上下文,获取toast工具,获取Navigator。
    MainComponent有两个标记@PerActivity和@Component并继承了ActivityComponent。里边有两个方法inject(mainActivity)方法和获取mainFragmentComponent实例的方法。
    MainFragmentComponent类中有两个标记@PerActivity和@Subcomponent,还有一个inject(mainFragment)方法。

    modules封装第三方类库使用,简单的工厂模式。
    AppModule被@Module标记,里边有个三个方法provideContext,provideNavigator,provideToastUtil都被 @Provides 和@Singleton标记。
    ActivityModule也被@Module标记,在构造方法中传入了activity实例,并通过被@Provides 和 @PerActivity 标记的provideActivity方法return出去。
    MainModule也被@Module标记,里边只有1个@Provides标记的provideUserData()方法

    scopes作用域包只有被@Scope和@Retention标记的PerActivity接口。

    presenter包下只有MainPresenter这个类,里边有一个静态接口IUserView和它的set方法与实例。它的构造方法被@Inject标记并传入了GetUserData的实例,通过getUser方法给接口传递了数据

    view包下 BaseActivity 有1个getAppComponent方法,BaseFragment没有方法。
    MainActivity实现了MainFragment中的一个监听接口,通过DaggerMainComponent.builder()方法获取了ActivityModule的对象并调用了inject方法,提供了getMainComponent方法 return这个对象。
    mainFragment这个类中通过@Inject 获取了mainPresenter、toastUtil、multiConstruct三个实例在onActivityCreated方法中得到MainFragmentComponent对象并实现inject方法,通过mainPresenter的setUserView 设置了数据,在onCreateView的两个点击事件中通过mainPresenter获取了数据,通过toastUtil展示了toast.

    在包的最外层App的onCreate中获取了AppModule对象并提供了return方法。
    MultiConstruct类中 @Inject了构造函数
    Navigator被@Singleton标记了。
    ToastUtil封装了展示吐司的方法。

    总结一下:
    di包的components包中都是注入器,有app注入器、activity注入器、main注入器、fragment注入器。main注入器继承了activity注入器,对MainActivity进行依赖注入。
    Module是一个提供类实例的类,通过标注关联了2个实例MainModule和ActivityModule,加入main注入器,他们的方法都被@Provides标注了。
    当module中的类需要创建实例的时候需要用@PerActivity标记出来。
    MainComponent继承了ActivityComponent并采用dependencies标记依赖了 AppComponent。
    MainFragmentComponent通过@PerActivity与MainComponent声明了相同的作用域并通过@Subcomponent声明被包含的。

    工厂模式也可以降低耦合度。
    依赖注入:从容器中查找合适的对象,对当前的对象进行赋值。
    被@Component标注类为注入器,bean生成工厂类,运行后在apt-debug包下。
    注入器不能直接new 只能通过创建器进行创建。

    @Inject只能针对无参构造,可以修改源代码。

    @Module与@Provides 针对有参构造和jar包使用。对工厂模式类进行@Module,对实例类@Provides 方法用Provides 开头。在component类中标注出module的类,inject方法查找界面@inject的类进行赋值。调用时需多指定创建实例的工厂。

    获取注入器 需要编译 生成dagger开头的类

    相关文章

      网友评论

          本文标题:关于MVP+Dagger2的一些知识

          本文链接:https://www.haomeiwen.com/subject/hbdpkftx.html