Dragger2的原理
来源:互联网 发布:app的运营数据分析 编辑:程序博客网 时间:2024/06/03 23:40
转自http://www.jianshu.com/p/39d1df6c877d
博主讲的实在是好, 我简单记录一下, 方便自己的记忆.
(1)使用场景, 一个类需要使用另一个类作为成员的时候.
public class ClassA { ... ClassB b; ... public ClassA() { b = new ClassB(); } public void do() { ... b.doSomething(); ... }}这个时候就产生了依赖问题,ClassA依赖于ClassB,必须借助ClassB的方法,才能完成一些功能。这样看好像并没有什么问题,但是我们在ClassA的构造方法里面直接创建了ClassB的实例,问题就出现在这,在ClassA里直接创建ClassB实例,违背了单一职责原则,ClassB实例的创建不应由ClassA来完成;其次耦合度增加,扩展性差,如果我们想在实例化ClassB的时候传入参数,那么不得不改动ClassA的构造方法,不符合开闭原则.
(2)使用Dragger2
dependencies { classpath 'com.android.tools.build:gradle:2.1.0' //添加apt插件 classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } apply plugin: 'com.android.application' //添加如下代码,应用apt插件 apply plugin: 'com.neenbedankt.android-apt' ... dependencies { ... compile 'com.google.dagger:dagger:2.4' apt 'com.google.dagger:dagger-compiler:2.4' //java注解 compile 'org.glassfish:javax.annotation:10.0-b28' ... }
(3)举个例子
-----------------------------------------------------------------------------------------------------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)//连接依赖与inject类的桥梁public interface MainComponent { void inject(MainActivity activity);}==============================================================================
(4)Drager2的注入过程分析
@Inject 带有此注解的属性或构造方法将参与到依赖注入中,Dagger2会实例化有此注解的类@Inject
MainPresenter mainPresenter; //实例化此类
@Module 带有此注解的类,用来提供依赖,里面定义一些用@Provides注解的以provide开头的方法,这些方法就是所提供的依赖,Dagger2会在该类中寻找实例化某个类(@inject)所需要的依赖。
@Component 用来将@Inject和@Module联系起来的桥梁,从@Module中获取依赖并将依赖注入给@Inject
DaggerMainComponent.builder()
.mainModule(new MainModule(this))//实例化module
.build()
.inject(this);//注入给inject类对象
(5)dragger2注入原理
它是通过apt插件在编译阶段生成相应的注入代码.MainPresenter的实例化过程。(见下面第一步)MainPresenter会对应的有一个工厂类,在这个类的get()方法中进行MainPresenter创建,(见下面第二步)而MainPresenter所需要的View依赖,是由MainModule里定义的以provide开头的方法所对应的工厂类提供的
<1>被@Inject的类, 在rebuild工程的时候, 会生成MainPresenter_Factory
在/app/build/generated/apt/debug/目录下.
主要功能:利用依赖的Provider(@Module标记的类), 生成被@inject标记的类.
-----------------------------------------------------------------------------------------------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); }}===========================================================<2>在MainModule中定义的@Provides修饰的方法会对应的生成一个工厂类,这里是MainModule_ProvideMainViewFactory, 上面的MainPresenter(viewProvider.get());
这个Provider, 就是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); }}=========================================================================
<3>以上创建过程的发起人, DaggerMainComponent , @Module和@Inject的桥梁
他的主要作用.
根据调用流程, 逐步分析源码:
DaggerMainComponent.builder()
.mainModule(new MainModule(this))//实例化module
.build()
.inject(this);//将生成的@Inject对象, 送给MainActivity.
I.根据我们自己写的MainModule(可以get到activity实现的 MainContract.View).创建MainModule_ProvideMainViewFactory.
II.根据MainModule_ProvideMainViewFactory(实际继承自Provider),
创建MainPresenter_Factory
III.根据MainPresenter_Factory创建MembersInjector<MainActivity>
IV. MainActivity_MembersInjector里面会获取@Inject的真正实例, 就完成创建了.
MainActivity_MembersInjector里的关键代码injectMembers(MainActivity.this), 会把@inject实例, 传递给injectMembers的参数(MainActivity. mainPresenter)
--------------------------------------------------------------------------------------------------------------------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); } 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; } }}=======================================================================----------------------------------------------------------------------------------------------------------------------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(); }}=========================================================================
阅读全文
0 0
- Dragger2的原理
- dragger2 的使用详解
- Dragger2的简单使用
- Dragger2的使用
- dragger2的入门基础
- dragger2
- Dragger2、RxJava和Retrofit的巧妙结合
- Dragger 2遇到的坑 Dragger2详解 Dragger2学习最好的资料
- Dragger 2遇到的坑 Dragger2详解 Dragger2学习最好的资料
- 关于Dragger2与RXjava集合框架的项目随笔
- Dragger2入门
- Dragger2 浅入浅出
- Dragger2使用
- 基于Retrofit2.0+RxJava+Dragger2实现不一样的Android网络构架搭建
- Retrofit2.0+RxJava+Dragger2实现不一样的Android网络架构搭建
- 基于Retrofit2.0+RxJava+Dragger2实现不一样的Android网络构架搭建
- Dragger2 学习笔记
- Dragger2使用心得笔记
- pc端和手机端禁用滚动条
- linux获取目录下文件 包含子目录
- Qt 数据库模型(QSqlQueryModel,QSqlTableModel)获取模型中的所有数据
- Import Spaghetti
- 中山市选2008 小树 题解
- Dragger2的原理
- Git使用宝典
- HDUOJ1312Red and Black(BFS)
- 编辑框Edit_列表框ListBox_组合框ComBox默认内容设置以及获取IP控件内容
- MyBatis之注解开发-yellowcong
- 算法第12周Regular Expression Matching[hard]
- 利用python多线程更新数据
- 呼吸灯
- tf.get_default_graph()