Android - Dagger2 使用和原理
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/
关于依赖的实现
这篇文章讲的不错,我的理解如下:
整个实现步骤大概是这样的
假设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();
- @Override
- public void injectMembers(Bus instance) {
- if (instance == null) {
- throw new NullPointerException("Cannot inject members into a null reference");
- }
- instance.engine = engineProvider.get();
- }
Android - Dagger2 使用和原理的更多相关文章
- (转)Android 系统 root 破解原理分析
现在Android系统的root破解基本上成为大家的必备技能!网上也有很多中一键破解的软件,使root破解越来越容易.但是你思考过root破解的 原理吗?root破解的本质是什么呢?难道是利用了Lin ...
- Android系统Recovery工作原理
Android系统Recovery工作原理之使用update.zip升级过程分析(一)---update.zip包的制作 http://blog.csdn.net/mu0206mu/article/d ...
- Android启动篇 — init原理(二)
======================================================== ================================== ...
- Android启动篇 — init原理(一)
======================================================== ================================== ...
- Android热修复技术原理详解(最新最全版本)
本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...
- Android FoldingLayout 折叠布局 原理及实现(二)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/44283093,本文出自:[张鸿洋的博客] 1.概述 在上一篇Android Fo ...
- Android 长截屏原理
https://android-notes.github.io/2016/12/03/android%E9%95%BF%E6%88%AA%E5%B1%8F%E5%8E%9F%E7%90%86/ a ...
- Android 系统 root 破解原理分析 (续)
上文<Android系统root破解原理分析>介绍了Android系统root破解之后,应用程序获得root权限的原理.有一些网友提出对于root破解过程比较感兴趣,也提出了疑问.本文将会 ...
- Android自复制传播APP原理学习(翻译)
Android自复制传播APP原理学习(翻译) 1 背景介绍 论文链接:http://arxiv.org/abs/1511.00444 项目地址:https://github.com/Tribler ...
随机推荐
- Lerning Entity Framework 6 ------ Inserting, Querying, Updating, and Deleting Data
Creating Entities First of all, Let's create some entities to have a test. Create a project Add foll ...
- 解决ssh远程连接错误问题
使用 Xshell 远程连接服务器时,经常会出现这么个错误提示 WARNING! The remote SSH server rejected X11 forwarding request. ➜ ~ ...
- Java 基础笔记
1. 面向对象三大特性:封装,继承,多态,java面向对象的最终父类是:Object 2. getInstance() 单实例设计模式factory() 工厂模式build() 建造者模式 3. 静态 ...
- D15——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D15 20180926内容纲要: 1.CSS介绍 2.CSS的四种引入方式 3.CSS选择器 4.CSS常用属性 5.小结 6.练习 1 CSS介绍 层叠样式表 ...
- shopify网站转化率优化之结账页checkout优化
昨天分享了“利用GOOGLE地图API实现shopify结账页checkout地址自动填写地址字段”是个非常屌的功能,但shopify默认的结账页checkout是这样的如图 [caption id= ...
- Wilcoxon-Mann-Whitney rank sum test
Wilcoxon-Mann-Whitney ranksum test 无节点状况,假定为样本服从类似形状,如果不是类似形状的话,秩的比较没有过多意义. X有m个数,Y有n个数 \(H_0:\mu_1= ...
- [Umbraco] Data Type的扩展编程
继续从上面的Data Types的自定义控件说起.前面用到了自定义控件的数据绑定,虽然这使得我们可以调用外部数据了,但这似乎还比较死板,如果再调用其他数据,还得再创建一个控件,那样的话就会出现类似的功 ...
- odoo开发笔记 -- 数据库备份策略
odoo默认的数据库为postgresql数据库, PG是个非常强大的数据库,也是未来的一个趋势. 对于odoo的数据备份,odoo提供了自己的备份方式, 1. 从前台页面.输入odoo应用访问地址, ...
- c++的动态绑定和静态绑定
为了支持c++的多态性,才用了动态绑定和静态绑定. 1.对象的静态类型:对象在声明时采用的类型.是在编译期确定的. 2.对象的动态类型:目前所指对象的声明.在运行期决定.对象的动态类型可以更改,但是静 ...
- JavaScript --Window-对话框
-----038-Window-对话框.html----- <!DOCTYPE html> <html> <head> <meta http-equiv=&q ...