Dagger-Android+mvp搭配lifecycle+bu

2020-01-20  本文已影响0人  youxiaochen

前言:

Dagger编译期时依赖注入框架,使用代码生成而不用反射,更大程度的帮助MVP降低耦合度,mvp一对多,这里重点讲Dagger在Android中的使用,阅读此文章前提要懂得Dagger2基础的使用,文章中若有错误的请多多指点

基础篇链接(讲的很详细感谢)https://blog.sunhapper.tk/sync/dagger2-cong-ru-men-dao-fang-qi-gai-nian-jie-shao/

image.png

一:Dagger-Android的使用思路(这里把dagger中的Component叫做注入容器吧)

这里重点要理解Subcomponent的使用,Dagger-Andoird主要使用的就是SubComponent注入模式

1:在实际开发中解耦最多的就是Activity, Fragment,这里就以这两个为例

先看下Application与Activity,Fragment结构关系(参照AndroidManifest.xml结构)

Application(全局单类) -->> Activity(多个activity共享着application引用)
Activity -->> Fragment (多个Fragment共享附着的Activity引用, 当然也就共享着Application引用)
Fragment -->> Child Fragment (多个ChildFragment共享着Parent Fragment引用,也共享着附着的Activity引用,也共享着Application引用)...一直循环

(当然Application中还有Service, BroadCastReceiver, ContentProvider, 这种结构其实就是AndroidManifest.xml结构,只是不包含Fragment)

2:Dagger既然运用到Android中,那就肯定要按这种结构思路来

同样的道理

注入容器 Application Component -->> Activity SubComponent

(多个Activity的注入容器就可以共享着Application注入容器)

Activity SubComponent -->> Fragment SubComponent

(多个Fragment的注入容器就可以共享附着的Activity注入容器, 也共享Application的注入容器)

Fragment SubComponent -->>Child Fragment SubComponent

(多个Child Fragment注入容器就共享着Parent Fragmet的注入容器,共享附着的Activity注入容器, 也共享Application的注入容器)

这样在Application注入容器中可以注入些单例或全局需要的类, 可以直接供Activity及再下一层的Fragment直接注入使用或当作参数注入使用, 而Activity注入容器也可以直接提供(如在Fragment中注入需要Activity的Context引用时)的Context注入
而这一切谷歌的dagger-android已经帮我们实现了,我们只需要考虑的是哪个Component中注入哪些需要的成员
3:Dagger-android依赖
    compile 'com.google.dagger:dagger:2.16'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
    // dagger.android
    compile 'com.google.dagger:dagger-android:2.16'
    compile 'com.google.dagger:dagger-android-support:2.16'
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.16'

二:Dagger-android的具体实现(dagger-android已提供好了DaggerApplication, DaggerActivity,DaggerFragment, DaggeService,AndroidInjection等类)

1.创建AppComponent,最上层的注入容器,这个也是全局注入容器

AndroidSupportInjectionModule里面包含了AndroidInjectionModule,用于四大组件的注入和Fragment与support v4 Fragment的注入
AppModule中用于注入些全局类(一般都是全局单例)

//
public class App extends DaggerApplication {
    @Override
    protected AndroidInjector<App> applicationInjector() {
        return DaggerAppComponent.builder().create(this);
    }
}

@Singleton
@Component(modules = {AndroidSupportInjectionModule.class,
        AppModule.class,
        ActivitysBuilder.class
        //这里还可以配置Service, ContentProvider, BroadcastReceiver的注入容器
})
public interface AppComponent extends AndroidInjector<App> {
    @Component.Builder
    abstract class Builder extends AndroidInjector.Builder<App> {
    }
}

@Module
public class AppModule {
    /**
     * 可用于构造函数需要参数Application的注解
     * @param app
     * @return
     */
    @Provides
    @Singleton
    Application application(App app) {
        return app;
    }
  //这里也可以用来注入更多单例全局类, 而且这里的返回值都可以直接在
  //SubComponent中直接注入使用,也可以当作参数直接注入使用    
}
2:Activity SubComponent的创建(不用写)

每个Activity都要写对应的SubComponent多麻烦,dagger-android为我们提供了注解ContributesAndroidInjector
ActivitysBuilder.class 这里ContributesAndroidInjector主要就是帮我们自动生成各Activity Component注入容器, 只需要配置各自的注入Module即可

@Module
public interface ActivitysBuilder {
    @ActivityScope
    @ContributesAndroidInjector(modules = MainActivityModule.class)
    MainActivity injectMainActivity();

    @ActivityScope
    @ContributesAndroidInjector(modules = SecondActivityModule.class)
    SecondActivity injectSecondActivity();

    @ActivityScope
    @ContributesAndroidInjector(modules = ThreeActivityModule.class)
    ThreeActivity injectThreeActivity();
}
3:Fragment ChildFragment SubComponent的创建(同样不用写)

例如SecondActivityModule中有嵌套Fragment, Fragment中又嵌套ChildFragment

@Module(includes = TestFragmentBuilder.class)
public class SecondActivityModule {
    ...
}

@Module
public interface TestFragmentBuilder {
    @FragmentScope
    @ContributesAndroidInjector(modules = {TestFragmentModule.class, TestChildFragmentBuilder.class})
    TestFragment injectTestFragment();
}
4:注意事项
a:TestFragmentBuilder和TestChildFragmentBuilder其实都可以在AppComponent中配置modules(坚决不推荐这样使用,这样Fragment注入容器不是Activity的subComponent就共享不到所附着的Activity的注入容器)
b:通过整个注入容器的入口AppComponent中,通过生成的DaggerAppcomponent源码可以看到,该注入容器在生成的时候同时会初始化moduler中需要注入的Provider,和ActivityBuilder中所有ActivityComponent的Builder的Provider类, 同理Activity生成时, Activity的注入容器在初始化时也会生成所有配置的FragmentComponent Builder的Provider类,所以在各层级的Module类中一定要按顺序写好ContributesAndroidInjector,各层的Module注入哪些需要的对象都要严格按照上面讲的结构来
private void initialize(final Builder builder) {
    this.mainActivitySubcomponentBuilderProvider =
        new Provider<ActivitysBuilder_InjectMainActivity.MainActivitySubcomponent.Builder>() {
          @Override
          public ActivitysBuilder_InjectMainActivity.MainActivitySubcomponent.Builder get() {
            return new MainActivitySubcomponentBuilder();
          }
        };
    this.secondActivitySubcomponentBuilderProvider =
        new Provider<ActivitysBuilder_InjectSecondActivity.SecondActivitySubcomponent.Builder>() {
          @Override
          public ActivitysBuilder_InjectSecondActivity.SecondActivitySubcomponent.Builder get() {
            return new SecondActivitySubcomponentBuilder();
          }
        };
    this.threeActivitySubcomponentBuilderProvider =
        new Provider<ActivitysBuilder_InjectThreeActivity.ThreeActivitySubcomponent.Builder>() {
          @Override
          public ActivitysBuilder_InjectThreeActivity.ThreeActivitySubcomponent.Builder get() {
            return new ThreeActivitySubcomponentBuilder();
          }
        };
    ......
  }

以上只贴出一部分代码,搭配lifecycle+butterknife+rxandroid+retrofit2更多代码连接:https://github.com/youxiaochen/dagger-android-mvp

总结:Dagger注入其实是在编译时生成一些代码注入, 而这种从App到Fragment的结构可以在生成的DaggerAppComponent类中全部体现出来,了解一款框架的使用一定要了解它的源码及执行步骤,这样也可以更好的理解Dagger2这款神器, 这里只介绍Dagger-android的注入思路与结构, 现实开发中可以再自己拓展, 有错误的地方也请多多指点谢谢!

更多文章请关注:http://www.jianshu.com/u/b1cff340957c

上一篇 下一篇

猜你喜欢

热点阅读