• dagger2系列之依赖方式dependencies、包含方式(从属方式)SubComponent


      本篇是实战文章,从代码的角度分析这两种方式。本文参考自下列文章:

          http://www.jianshu.com/p/1d42d2e6f4a5

          http://www.jianshu.com/p/94d47da32656

      一般在项目中我们需要全局使用app或者其他,这个时候就需要有一个全局的Component作为桥梁,提供给使用方使用。一个Component可以依赖一个或多个Component,并拿到被依赖Component 暴露 出来的实例

    <一>依赖关系

    全局提供App实例类、上下文Context

    @Module
    public class AppModule5 {
    
        private App5 app;
    
        public AppModule5(App5 app) {
            this.app = app;
        }
    
        @Provides
        public App5 provideApp() {
            return app;
        }
    
        @Provides
        Context provideApplicationContext() {
            return app.getApplicationContext();
        }
    }

    提供 全局提供App实例类、上下文Context桥梁,该Component会被其他Component依赖

    @Component(modules = {AppModule5.class})
    public interface AppComponent5 {
        void inject(App5 app);
    
        //因为AppComponent会被dependencies,所以此处Module中提供的内容,我们需要在此处声明一下
        App5 getApp();
        Context getApplicationContext();
    }

      由于AppComponent5会被其他Component依赖,所以此处需要显示地声明AppModule5中提供的东西,此处的方法名任意!!!

    App被全局提供

    public class App5 extends Application {
    
        private AppComponent5 mAppComponent5;
    
        @Override
        public void onCreate() {
            super.onCreate();
            mAppComponent5 = DaggerAppComponent5.builder().appModule5(new AppModule5(this)).build();
            mAppComponent5.inject(this);
        }
    
        public AppComponent5 getAppComponent5(){
            return mAppComponent5;
        }
    
    }

      若Module的构造器需要参数,我们就需要在这里appModule5(new AppModule5()),若Module的构造器中不需要参数,此处可以省略!!!需要通过这种方式将参数传递进去。

    提供被依赖类:

    @Module
    public class ActivityModule5 {
    
        @Provides
        public DependencyPresenter getDependencyPresenter(App5 app){
            return new DependencyPresenter(app);
        }
    }

    桥梁:

    @Component(dependencies = AppComponent5.class,modules = ActivityModule5.class)
    public interface ActivityComponent {
        void inject(TargetActivity5 activity5);
    }

      使用了Component的dependencies属性,ActivityModule5提供被依赖类,AppComponent5提供被依赖类的参数(全局提供)。

    被依赖类:此处没用@inject修饰构造器

    public class DependencyPresenter {
    
        public DependencyPresenter(App5 app){
            Log.d("Dagger.class","DependencyPresenter-----构造器------(app == null)?????:"+(app == null));
        }
    
        public void printMethod(){
            Log.d("Dagger.class","DependencyPresenter-----printMethod()-----");
        }
    
    }

    目标类

    public class TargetActivity5 extends AppCompatActivity {
    
        @Inject
        DependencyPresenter mDependencyPresenter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            App5 app5  = (App5) this.getApplication();
    
            DaggerActivityComponent.builder().appComponent5(app5.getAppComponent5()).build().inject(this);
    
            mDependencyPresenter.printMethod();
        }
    }

      由于ActivityComponent依赖AppComponent,所以需要在此处添加声明appComponent(app5.getAppComponent)。

      由此得到结论:需要在Component中显示的声明提供 被依赖类 的方法(方法名任意)

        1 同一个Component的两个Module之间,当ModuleA需要ModuleB提供参数,在Component中需要提供获取参数的方法

        2 ComponentA和它所依赖的ComponentB之间,若ComponentA需要ComponentB提供参数,在ComponentB中需要显示声明方法

    <二>包含方式(从属方式)@SubComponent

      当我们的Component需要依赖全局的Component提供的实例或者参数的时候,我们上面的实现方式是选择Component的dependencies属性,此时需要在被依赖的Component中有显示的声明。这里介绍另一种方法,包含方式。相比于依赖方式,包含方式不需要在父Component中显示的提供方法,就可以拿到想要的东西。下面看一下代码:

    使用@Subcomponent注解标注ActivityModule6,代表它是子Component

    @Subcomponent(modules = ActivityModule6.class)
    public interface ActivityComponent6 {
        void inject(TargetActivity6 activity5);
    }

    父Component:

    @Component(modules = {AppModule6.class})
    public interface AppComponent6 {
        void inject(App6 app);
    
        ActivityComponent6 getSubComponent();
    }

      需要在父Component中声明自己的子Component,方法名任意。如果ActivityComponent6中的Module的构造器需要参数,则在此处传递进去,譬如:

        ActivityComponent6 getSubComponent(new ActivityModule6("参数"));

    目标类:使用方式上也有区别

    public class TargetActivity6 extends AppCompatActivity {
    
        @Inject
        DependencyPresenter6 mDependencyPresenter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            App6 app6  = (App6) this.getApplication();
            app6.getAppComponent6().getSubComponent().inject(this);
            mDependencyPresenter.printMethod();
        }
    }

      其他类均没有变化。依赖方式、包含方式介绍到此为止~更多的内容请参看上面的链接!!!

  • 相关阅读:
    Ajax
    模型层补充
    Django models.py 模型层(单表多表查询)
    Django 模板层
    Django views.py 视图层
    Django urls.py 路由层
    Browser Security-同源策略、伪URL的域
    Browser Security-css、javascript
    Browser Security-基本概念
    exp2:// 一次存储型XSS从易到难的挖掘过程
  • 原文地址:https://www.cnblogs.com/lang-yu/p/6241068.html
Copyright © 2020-2023  润新知