Dagger2的组件依赖及使用详解
来源:互联网 发布:科目二约车软件 编辑:程序博客网 时间:2024/04/29 01:00
上一篇详细讲解了Dagger2的大部分使用及基础知识,不太了解的朋友可以去看看http://blog.csdn.net/lylodyf/article/details/52981910。这一篇讲讲组件依赖及具体的使用。
组件依赖
顾名思义当然就是组件之间的依赖,即Component之间的依赖,不知是否发现Component有个属性是dependencies,用以指定依赖的Component。那么组件依赖有什么用处呢?想象这样一个场景,有一个MainModule里面的实例化方法需要一个参数假设为Context,现在无法获得这个Context,但是在另一个组件AppComponent里面有,现在我们只需要让管理MainModule的MainComponent组件依赖APPComponent就可以轻松实现。也就是说组件依赖可以让子组件获得父组件暴露出来的对象。
使用组件依赖有几点需要注意:
1.两个依赖的组件不能共享作用域,什么意思,也就是他们指定的作用域一定要不同
2.父组件必须暴露出子组件所需要的对象
下面通过一个具体实例来说明,其中包含了Dagger2的具体使用实践。
目录结构
AppComponent
@Singleton@Component(modules = AppModule.class)public interface AppComponent { //Exposed to sub-graphs. Context context(); ToastUtil toastUtil(); SharedPreferences sharedPreferences();}可以看到这里面有三个方法,之前不是说过实现组件依赖父组件必须暴露出方法吗,这里就是向子组件暴露了三个方法。
AppModule
@Modulepublic class AppModule { private MyApplication application; public AppModule(MyApplication application) { this.application = application; } @Provides @Singleton Context provideContext() { return application; } @Singleton @Provides ToastUtil provideToastUtil(Context context) { return new ToastUtil(context); } @Singleton @Provides SharedPreferences provideSP(Context context) { return context.getSharedPreferences("config", Context.MODE_PRIVATE); }}这里面有三个实例化的方法,方法上面的Scope必须要和对应的Component的Scope一致。也许有人会问其中有两个方法传入的参数Context是从哪里来的,这是由于这里面还有一个方法provideContext(),返回的正是需要的Context。所以如果在这里还有一个方法需要参数ToastUtil,这里也有返回ToastUtil的方法,也可以提供。
MainComponent
@UserScope@Component(modules = MainModule.class, dependencies = AppComponent.class)public interface MainComponent { void inject(MainActivity activity);这里指定了依赖AppComponent,有一个注射到MainActivity得方法,很好理解吧。至于@UserScope是一个自定义的Scope,不了解的可以去看看我上篇博客。之前也说到和依赖的父组件的Scope必须不同,所以不能使用@Singleton
MainModule
@Modulepublic class MainModule { @Named("a") @UserScope @Provides User provideUser1(Child child) { return new User(child); } @Named("b") @UserScope @Provides User provideUser2(Child child) { return new User(child); }}只有两个返回User的实例化方法,@Named是限定符,不了解的也可以去看看上篇博客。User和Child就是两个普通的类,这里发现传入的参数是Child,那么有人又有疑问了,这里并没有返回Child的方法啊,这个Child又是从哪里来呢?下面我们先看看User类和Child类
User
public class User { public User(Child child) { Log.i("lzy", "调用User类无参构造方法"); }}
Child
public class Child { @Inject public Child() { Log.i("lzy", "调用Child类的无参构造方法"); }}
可以看到User并没有什么特别,只是构造函数需要传入一个Child。但是看看Child,构造函数上面加了@Inject注解,上一篇博客我们不是讲过提供构造方法有两种方式吗,先到Module中找,没有找到会找有@Inject的构造函数。所以上面的Child就是从这里来的。
MyApplication
public class MyApplication extends Application { private AppComponent appComponent; @Override public void onCreate() { super.onCreate(); appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build(); } public AppComponent getAppComponent() { return appComponent; }}在Application中实例化了APPComponent,并且向外提供一个获取它的方法。当然要记得在manifest文件中配置。
MainActivity
public class MainActivity extends AppCompatActivity { private static final String TAG = "lzy"; @Named("a") @Inject User user; @Inject SharedPreferences sp; @Inject ToastUtil toastUtil; @Inject TestClass test; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DaggerMainComponent.builder().appComponent(getAppComponent()).mainModule(new MainModule()) .build().inject(this); Log.i(TAG, "User: " + user); Log.i(TAG, "SharedPreference: " + sp); Log.i(TAG, "test: " + test); toastUtil.showToast("呵呵哈哈哈"); } private AppComponent getAppComponent() { return ((MyApplication) getApplication()).getAppComponent(); }}
在这里调用了 DaggerMainComponent.builder().appComponent(getAppComponent()).mainModule(new MainModule()).build().inject(this)把MainActivity注入到MainComponent里面,并且声明了四个对象,User、SharedPreference、ToastUtil和TestClass
看看打印出来的日志
发现全部都不是空的,并且显示出了Toast。但是记得我们只在MainModule中提供了User的实例化方法吗,然后SharedPreference和ToastUtil也不为空,这自然就是因为依赖的APPComponent的原因。
对了这个TestClass有是什么东东,好像在其他地方都没有使用出现过,为什么打印出来又不为空呢
TestClass
@UserScopepublic class TestClass { @Inject public TestClass() { }}很简单的一个自定义类,只是制定了和MainComponent一样的作用域和在构造函数上面添加了@Inject,这样就可以直接使用了。
至此完毕,所以,你学会了吗
源码地址
- Dagger2的组件依赖及使用详解
- 关于Dagger2组件的实现方法及使用
- 依赖注入Dagger2详解
- Android 神兵利器Dagger2使用详解(四)Scope注解的使用及源码分析
- dagger2使用详解
- Dagger2 使用详解
- Dagger2 使用详解
- dagger2使用详解
- Dagger2使用详解
- Dagger2 使用详解
- Dagger2概念及使用
- 依赖注入神器:Dagger2详解系列
- Dagger2使用(三)Dagger2依赖注入-注解说明
- Dagger2----一个最简单的Dagger2依赖的实现
- Android项目使用Dagger2进行依赖注入
- Android中使用Dagger2进行依赖注入
- Android 依赖注入框架 Dagger2使用
- Dagger2使用(二)“依赖” “注入” 基本概念
- 扑克牌类
- 【tju】【dp】调整队形
- Android设计模式之单例模式的七种写法
- spring整合mybatis文件
- 厉害了!家里来了黑科技
- Dagger2的组件依赖及使用详解
- CentOS-6.t将安装光盘做为YUM库来安装程序
- apache ant编译项目的一个通用例子
- spring 定时器
- AngularJS入门之如何快速上手(详细讲解什么是angular)
- 实现js输入框只允许输入金额
- C语言的简单小例题程序
- Hibernate实体关系关联映射中配置文件的编写
- BookList