Dagger 2从浅到深(五)
来源:互联网 发布:python模块化编程实例 编辑:程序博客网 时间:2024/06/04 23:29
Dagger系列:
- Dagger 2从浅到深(一)
- Dagger 2从浅到深(二)
- Dagger 2从浅到深(三)
- Dagger 2从浅到深(四)
- Dagger 2从浅到深(五)
- Dagger 2从浅到深(六)
- Dagger 2从浅到深(七)
- Dagger 2应用于Android的完美扩展库-dagger.android
总所周知的是,Android的内存是十分昂贵的,所以,能省就省。这也造成了,有时候想延迟实例化对象,在需要的时候,才会进行实例化。就像冰箱里的水果一样,等我想吃的时候,才会拿出来,保证它的新鲜度。
又有时候,注入的是实例的列表,而不是单个实例的值。如果列表少,还可以重复调用@Inject注入实例。如果列表说在几十甚至上百时,也重复调用@Inject么?感觉有点繁琐哦。
Lay<T>和Provider<T>,不由自主的进入的我们的视线,它又给我们带来什么样的惊喜呢!!!
Lazy<T>
对于任何绑定的对象T,当你想惰性实例化它时,都可以创建一个延迟实例化的Lazy<T>。当你需要它时,调用get()方法时,就会实例化对象。
public class BananaBean { @Inject public BananaBean() { Log.d("test", "BananaBean()"); }}public class FruitActivity extends AppCompatActivity { *** @Inject Lazy<BananaBean> mBananaBeanLazy; @Override protected void onCreate(Bundle savedInstanceState) { *** BananaBean beanA = mBananaBeanLazy.get(); // advanced.todo.com.daggerlearn.bean.BananaBean@3d061bc6 Log.d("test", beanA.toString()); BananaBean beanB = mBananaBeanLazy.get(); // advanced.todo.com.daggerlearn.bean.BananaBean@3d061bc6 Log.d("test", beanB.toString()); } ***}
现惰性注入了BananaBean的两个实例 - beanA和beanB,看它们的内存地址是一样的。另一方面,BananaBean的构造函数只有在创建beanA,也就是第一次调用get()方法时调用了一次。也就是说,Lazy只有第一次调用get()方法时,调用构造函数实例化对象,然后将该对象缓存。以后再调用get()方法时,都会返回缓存的实例,并且不会再调用构造函数,创建实例。
注意:
- 如果T是单例,那么Lazy<T>将是ObjectGraph内所有注入的实例;否则,每个注入点将创建自己的Lazy<T>实例。
- 无论如何,对任何给定的Lazy<T>实例的调用将返回相同的底层实例.
Provider<T>
有时您需要注入多个实例列表,而不是仅注入单个值。此时,有多种选择,比如工厂模式、Builder模式等。当然,你还有另外一种选择,那就是选择注入一个Provider <T>,而不只是T。
当Provider<T> 每次调用get()方法时,都会执行绑定逻辑并创建一个实例。
现有类BananaBean,其构造函数被@Inject注解。在FruitActivity类中,注入了Provider实例,然后调用其get()方法,创建BananaBean实例。
public class BananaBean { @Inject public BananaBean() { Log.d("test", "BananaBean()"); }}public class FruitActivity extends AppCompatActivity { *** @Inject Provider<BananaBean> mBananaBeanProvider; @Override protected void onCreate(Bundle savedInstanceState) { *** BananaBean beanA = mBananaBeanProvider.get(); BananaBean beanB = mBananaBeanProvider.get(); // advanced.todo.com.daggerlearn.bean.BananaBean@3d061bc6 Log.d("test", beanA.toString()); // advanced.todo.com.daggerlearn.bean.BananaBean@3d061bc6 Log.d("test", beanB.toString()); } ***}
从Log打印中,我们可以清晰看出来,每次调用get()方法,都会调用BananaBean的构造函数,实例化一个新的对象,而不像Lazy<T>那样将第一次创建的实例缓存。
这时,会有一个疑问,我们所知道的是,BananaBean被@Scope注解时,在Scope作用范围内,只有第一次注入时,调用构建函数,创建一个新的实例对象,然后将该对象缓存,后续的注入实例都是调用该缓存。Provder<T>中的T,被Scope注解时,会怎么样呢?下面,我们修改下BananaBean类,用@TodoScope注解它,但是FruitActivity不做任何修改。我们看mBananaBeanProvider调用get()方法时的效果:
@TodoScopepublic class BananaBean { @Inject public BananaBean() { Log.d("test", "BananaBean()"); }}public class FruitActivity extends AppCompatActivity { *** @Inject Provider<BananaBean> mBananaBeanProvider; @Override protected void onCreate(Bundle savedInstanceState) { *** BananaBean beanA = mBananaBeanProvider.get(); BananaBean beanB = mBananaBeanProvider.get(); // advanced.todo.com.daggerlearn.bean.BananaBean@3d061bc6 Log.d("test", beanA.toString()); // advanced.todo.com.daggerlearn.bean.BananaBean@3d061bc6 Log.d("test", beanB.toString()); } ***}
此时,在两次调用mBananaBeanProvider的get()方法时:
- BananaBean的构造函数被调用了一次
- beanA和beanB的内存一致
我们可以这么认为,尽管是Provider<T>提供注入的对象,但@Scope注解的功能依然存在。
其中,官方对Provider<T>的解释是:Provider<T>将通过get()方法提供T实例,通常是由注入器来实现。从Dagger 2从浅到深(四),我们已经了解到,Scope注解作用的核心是对注入器的控制,那么出现这样的效果,也就不足为奇了。
- Dagger 2从浅到深(五)
- Dagger 2从浅到深(一)
- Dagger 2从浅到深(二)
- Dagger 2从浅到深(三)
- Dagger 2从浅到深(四)
- Dagger 2从浅到深(六)
- Dagger 2从浅到深(七)
- Dagger 2
- Dagger 2学习笔记
- Dagger 2 入门
- Dagger 2 before
- Dagger 2 初体验
- dagger 2 详解
- Dagger
- Dagger
- dagger
- dagger
- Dagger 2应用于Android的完美扩展库-dagger.android
- linux,编译proc出错解决办法
- jquery dialog 置顶
- 机器人建模,规划和控制
- [leetcode]: 453. Minimum Moves to Equal Array Elements
- 编程语言中除法
- Dagger 2从浅到深(五)
- Java框架数据库连接池比较(c3p0,dbcp和proxool)
- java script 第四章
- Improving neural networks by preventing co-adaptation of feature detectors
- Ogre2.1 分析笔记(二)-程序启动流程
- Javascript闭包
- jfinal里面的sql查询拼接实例
- ORACLE触发器详解
- ubuntu16.04配置caffe2(仅cpu)