zoukankan      html  css  js  c++  java
  • Android

    Dagger2从入门到放弃再到恍然大悟

    http://www.jianshu.com/p/cd2c1c9f68d4

    http://www.jianshu.com/p/39d1df6c877d

    http://blog.csdn.net/u012943767/article/details/51897247

    源码解析:

    DEMO

    不依赖注入:

    public class MainActivity extends AppCompatActivity implements MainContract.View {
        private MainPresenter mainPresenter;
        ...
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //实例化presenter 将view传递给presenter
            mainPresenter = new MainPresenter(this);
            //调用Presenter方法加载数据
             mainPresenter.loadData();
    
             ...
        }
    
    }
    
    public class MainPresenter {
        //MainContract是个接口,View是他的内部接口,这里看做View接口即可
        private MainContract.View mView;
    
        MainPresenter(MainContract.View view) {
            mView = view;
        }
    
        public void loadData() {
            //调用model层方法,加载数据
            ...
            //回调方法成功时
            mView.updateUI();
        }

    依赖注入:

    public class MainActivity extends AppCompatActivity implements MainContract.View {
        @Inject
        MainPresenter mainPresenter;
        ...
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
             DaggerMainComponent.builder()
                    .mainModule(new MainModule(this))
                    .build()
                    .inject(this);
            //调用Presenter方法加载数据
             mainPresenter.loadData();
    
             ...
        }
    
    }
    
    public class MainPresenter {
        //MainContract是个接口,View是他的内部接口,这里看做View接口即可
        private MainContract.View mView;
    
        @Inject
        MainPresenter(MainContract.View view) {
            mView = view;
        }    
        public void loadData() {
            //调用model层方法,加载数据
            ...
            //回调方法成功时
            mView.updateUI();
        }
    
    @Module
    public class MainModule {
        private final MainContract.View mView;
    
        public MainModule(MainContract.View view) {
            mView = view;
        }
    
        @Provides
        MainView provideMainView() {
            return mView;
        }
    }
    
    @Component(modules = MainModule.class)
    public interface MainComponent {
        void inject(MainActivity activity);
    }

    分析

    注入的目的就是两个:

    1. 让view(Activity)得到 mainPresenter的依赖,可以调用它的方法

    2. 让mainPresenter得到view(Activity)的依赖,可以调用它的方法

    从源码看这两个目的实现

    DaggerMainComponent.builder()
                    .mainModule(new MainModule(this))
                    .build()
                    .inject(this);

    DaggerMainComponent.builder() 方法会实例化一个Build类并返回

    Build类

    Build类用来管理一个mainModule,并实例化DaggerMainComponent类。

    public static final class Builder {
        private MainModule mainModule;
    
        private Builder() {}
    
        public MainComponent build() {
          if (mainModule == null) {
            throw new IllegalStateException(MainModule.class.getCanonicalName() + " must be set");
          }
          return new DaggerMainComponent(this);
        }
    
        public Builder mainModule(MainModule mainModule) {
          this.mainModule = Preconditions.checkNotNull(mainModule);
          return this;
        }
      }

    而mainModule负责管理一个view,别的类可以通过他的get()方法得到他管理的view(activity)。

    @Module
    public class MainModule {
        private final MainContract.View mView;
    
        public MainModule(MainContract.View view) {
            mView = view;
        }
    
        @Provides
        MainContract.View provideMainView() {
            return mView;
       }   
    }

    所以这里

    DaggerMainComponent.builder()
                    .mainModule(new MainModule(this))

    就完成了把view(activity)依附到一个mainModule上,再实例化一个Build类管理mainModule,最后用这个Build来实例化DaggerMainComponent

    而DaggerMainComponent用来管理三个成员

    provideMainViewProvider : 如名字所说,管理着mainview,可以从中得到mainview

    mainPresenterProvider: 如名字所说,管理着mainPresenter,可以从中得到mainPresenter

    mainActivityMembersInjector:

    public final class DaggerMainComponent implements MainComponent {
      private Provider<MainContract.View> provideMainViewProvider;
    
      private Provider<MainPresenter> mainPresenterProvider;
    
      private MembersInjector<MainActivity> mainActivityMembersInjector;
    
      private DaggerMainComponent(Builder builder) {
        assert builder != null;
        initialize(builder);
      }
    
      public static Builder builder() {
        return new Builder();
      }
    
      @SuppressWarnings("unchecked")
      private void initialize(final Builder builder) {
    
        this.provideMainViewProvider = MainModule_ProvideMainViewFactory.create(builder.mainModule);
    
        this.mainPresenterProvider = MainPresenter_Factory.create(provideMainViewProvider);
    
        this.mainActivityMembersInjector = MainActivity_MembersInjector.create(mainPresenterProvider);
      }
    
      @Override
      public void inject(MainActivity activity) {
        mainActivityMembersInjector.injectMembers(activity);
      }
    
      ...
    }

    在Build的build()方法中创建了Dagger类的实例,从而调用了它的构造函数

    DaggerMainComponent.builder()
                    .mainModule(new MainModule(this))
                    .build()

    Dagger类的init()函数,首先用mainModule实例化了工厂类MainModule_ProvideMainViewFactory

    public final class MainModule_ProvideMainViewFactory implements Factory<MainContract.View> {
      private final MainModule module;
    
      public MainModule_ProvideMainViewFactory(MainModule module) {
        assert module != null;
        this.module = module;
      }
    
      @Override
      public MainContract.View get() {
        return Preconditions.checkNotNull(
            module.provideMainView(), "Cannot return null from a non-@Nullable @Provides method");
      }
    
      public static Factory<MainContract.View> create(MainModule module) {
        return new MainModule_ProvideMainViewFactory(module);
      }
    }

    然后用provideMainViewProvider实例化了MainPresenter_Factory工厂类

    public final class MainPresenter_Factory implements Factory<MainPresenter> {
      private final Provider<MainContract.View> viewProvider;
    
      public MainPresenter_Factory(Provider<MainContract.View> viewProvider) {
        assert viewProvider != null;
        this.viewProvider = viewProvider;
      }
    
      @Override
      public MainPresenter get() {
        return new MainPresenter(viewProvider.get());
      }
    
      public static Factory<MainPresenter> create(Provider<MainContract.View> viewProvider) {
        return new MainPresenter_Factory(viewProvider);
      }
    }

    这个工厂类实例化了MainPresenter并返回,所以可以通过工厂类mainPresenterProvider的get方法得到mainPresenter。

    public class MainPresenter {
        MainContract.View mView;
        @Inject
        MainPresenter(MainContract.View view) {
            mView = view;
        }
     }

    在实例化

    最后通过mainPresenterProvider实例化MainActivity_MembersInjector。我们看到这个类前面是MainActivity开头,因此可以想到是MainActivity对应得注入类,我们后面再分析这个类。

    public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
      private final Provider<MainPresenter> mainPresenterProvider;
    
      public MainActivity_MembersInjector(Provider<MainPresenter> mainPresenterProvider) {
        assert mainPresenterProvider != null;
        this.mainPresenterProvider = mainPresenterProvider;
      }
    
      public static MembersInjector<MainActivity> create(
          Provider<MainPresenter> mainPresenterProvider) {
        return new MainActivity_MembersInjector(mainPresenterProvider);
      }
    
      @Override
      public void injectMembers(MainActivity instance) {
        if (instance == null) {
          throw new NullPointerException("Cannot inject members into a null reference");
        }
        instance.mainPresenter = mainPresenterProvider.get();
      }
    
      public static void injectMainPresenter(
          MainActivity instance, Provider<MainPresenter> mainPresenterProvider) {
        instance.mainPresenter = mainPresenterProvider.get();
      }
    }

    MainActivity_MembersInjector类持有一个MainPresenterProvider,从injectMembers方法可以让一个view(activity)得到这个mainPresenter。

    另外MainPresenterProvider.get()方法实例化了MainPresenter

      @Override
      public MainPresenter get() {
        return new MainPresenter(viewProvider.get());
      }
    public class MainPresenter {
        MainContract.View mView;
        @Inject
        MainPresenter(MainContract.View view) {
            mView = view;
        }
     }

    至此MainPresenter就得到了View(Activity)的实例,可以调用它的方法,目的二实现

    最后看

    DaggerMainComponent.builder()
                    .mainModule(new MainModule(this))
                    .build()
                    .inject(this);

    调用了Dagger的inject方法

    @Override
      public void inject(MainActivity activity) {
        mainActivityMembersInjector.injectMembers(activity);
      }

    就是上面的injectMembers方法。至此activity就拿到了mainPresenter的实例,可以调用它的方法

    目的一实现。

    感谢:

    http://www.jianshu.com/p/cd2c1c9f68d4

    http://alighters.com/blog/2016/04/15/dagger2-indepth-understanding/

    http://chriszou.com/2016/05/10/android-unit-testing-di-dagger.html

    http://blog.nimbledroid.com/2016/03/07/performance-of-dependency-injection-libraries-zh.html

    http://google.github.io/dagger/

    关于依赖的实现

    Dagger2的使用以及源码分析

    这篇文章讲的不错,我的理解如下:

    整个实现步骤大概是这样的

    假设Bus类注入到MainActvitiy

    1.编译生成BusProvider类,Injector类,以及一些工厂类

    2.Dagger类初始化

    调用BusProvider的create()函数得到BusProvider类的实例

    如果create里需要busModule的provide参数则create(builder.busModule)

    再调用Injector的create()得到Injector类实例

    3.调用Injector的inject()方法,这个是在component里定义了inject给谁

    Injector类持有注入对象的实例,inject(this)时传入的

    @Override  
      public void injectMembers(Bus instance) {  
        if (instance == null) {  
          throw new NullPointerException("Cannot inject members into a null reference");  
        }  
        instance.engine = engineProvider.get();  
      }

    调用了provider.get()方法

    如果是构造函数,provider.get() 实现是 return new Bus();

    如果是module,provider.get() 实现是 return module.provide();

    1. @Override  
    2.   public void injectMembers(Bus instance) {  
    3.     if (instance == null) {  
    4.       throw new NullPointerException("Cannot inject members into a null reference");  
    5.     }  
    6.     instance.engine = engineProvider.get();  
    7.   }
  • 相关阅读:
    (05)ElasticSearch 倒排索引
    (04)ElasticSearch 安装Kibana
    (03)ElasticSearch 安装ElasticSearch-Head插件
    (02)ElasticSearch 安装
    (004)Linux http命令curl访问url
    (01)ElasticSearch概述
    (16)mongodb mapReduce分布式统计示例遇到的一个未解问题,求平均值不对,希望哪位大神给指点一下
    (15)mongodb mapReduce的概念及用法
    (14)mongodb aggregate聚集框架
    CodeForces
  • 原文地址:https://www.cnblogs.com/qlky/p/7253244.html
Copyright © 2011-2022 走看看