前言
我们接着上一篇博客《从源码剖析Dagger2:Component和Module入门》,继续从源代码级别来深入分析Dagger。本篇博客我们将重点介绍Scope和Subcomponent。
Scope
在任何编程语言中,对象都是定义在一定的作用域中的。一旦程序离开对应的作用域,该对象就要被销毁。在移动设备上,作用域的功能愈发显得重要。因为移动设备上的内存是有限的,只保留需要用到的对象,可以提高内存的使用效率,保证程序的运行流畅度。
MainViewModel只有在MainActivity中被用到,因此它的生命周期应该和MainActivity是一样的。我们可以为MainActivity定义一个新的Scope注解,并把它称之为MainActivityScope,代码如下:
@Scope
@MustBeDocumented
@Retention(value= AnnotationRetention.RUNTIME)
annotation class MainActivityScope
接下来,我们给MainComponent和MainViewModel分别加上MainActivityScope的注解,通过这种方式定义MainViewModel的Scope,并告诉MainComponent如何生成并维护MainViewModel的实例。代码如下所示。
@MainActivityScope
@Component(modules = [MainModule::class])
interface MainComponent {
...
}
@MainActivityScope
class MainViewModel @Inject constructor(sharedPreferences: SharedPreferences)
我们重新编译项目之后可以发现,和之前生成的代码相比,在为MainActivity注入依赖对象的时候,DaggerMainComponent不再每次创建新的MainViewModel的实例,而是通过Provider来获取MainViewModel的实例。如果MainViewModel已经被创建,就直接返回现有的MainViewModel实例。代码对比如下:
// 不加Scope注解的DaggerMainComponent
private MainViewModel getMainViewModel() {
return new MainViewModel(getSharedPreferences());
}
private MainActivity injectMainActivity(MainActivity instance) {
MainAc