当前位置:网站首页>Dagger2学习之Module的应用(二)
Dagger2学习之Module的应用(二)
2022-06-13 04:14:00 【rockyou666】
0x00.前言
Dagger2学习之配置和基础使用(一)中展示了最基本的Dagger2的应用。
在实际开发中有可能会出现两种情况,使用现在所掌握的技术手段是无法解决的。
1.有的时候有可能使用第三方的jar包。但是我们不可能在第三方jar包上写”@Inject”
2.构造函数可能需要传入参数。
正对以上的情况”@Module”就横空出世了。
0x01.Module类的应用
Module类:
@Module
public class ActivityModule {
@Provides
public User provideUser() {
return new User();
}
}Module类实现起来很简单,在实现好的实体类上加上”@Module”和”@Provides”。它本质上是一个工厂类。这个类替代了在文章Dagger2学习之配置和基础使用(一)中在User类的构造函数上的”@Inject”,那为什么要使用这个Module类来替代呢?
聪明的你一定知道是为了解决文章开头的那两个问题。解决的重点是”@Provides”和对应的provideUser方法。这样,无论是第三方框架还是自己写的代码,都可以放到”provideUser”中去。那么需要通过构造函数传递参数该怎么办?当然有办法,我们只需要在”provideUser”方法上传入参数类似下面的代码:
@Provides
public User provideUser(int age) {
return new User(age);
}
// 或者这样
@Provides
public User provideUser(int age) {
User user = new User();
user.setAge(age);
return user;
}
// 这样可以覆盖所有需要传入参数的场景当然,如果仅仅这样还是不行的。因为很明显,这里的方法参数是在哪里传入的呢,它并不是凭空出现的。
这里先给出Component代码:
@Component
public interface ActivityComponent {
void inject(MainActivity daggerActivity);
}注入到MainActivity的代码
public class MainActivity extends AppCompatActivity {
//注入
@Inject
User user;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
inject();
Log.v("tag", "user.name::"+user.name);
}
//注入行为
private void inject() {
DaggerActivityComponent.create().inject(MainActivity.this);
}上面不是提到的参数是如何传入的呢?其实只需要改造下
DaggerActivityComponent.create().inject(MainActivity.this);代码即可,代码如下:
DaggerActivityComponent.builder()
.activityModule(new ActivityModule(23))// 在这里传入需要的参数
.build()
.inject(this);这样,就彻底的解决了上面的两个问题。
0x02.关于Component
上一篇文章由于只是介绍最基本应用,没有介绍Component。那么在这里介绍下Component。
正如前面一篇文章说的。Component可以看成是医生使用的注射器,也可以看成是一个连接注入类和目标类的一个连接。
基本用法
首先新建立一个java接口,在接口上加上@Component。再在接口中提供一个抽象方法即可。
@Component
public interface ActivityComponent {
void inject(MainActivity activity);
}当然以上的代码是最简单的一种。
在使用了Module之后,需要在@Component通过”modules”来注明,你使用的是哪个Module。
@Component(modules = ActivityModule.class)
public interface ActivityComponent {
void inject(MainActivity activity);
}这样就可以在注入类和目标类建立一个联系。虽然这里实现了一个接口,但是实际上是通过dagger插件,生成java代码。生成的部分代码如下(上面已经加了注释):
/** *DaggerActivityComponent实现ActivityComponent *这里采用了类似构建者模式 */
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerActivityComponent implements ActivityComponent {
private Provider<User> provideUserProvider;
private MembersInjector<MainActivity> mainActivityMembersInjector;
private DaggerActivityComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
// 返回Builder类
public static Builder builder() {
return new Builder();
}
// 初始化
private void initialize(final Builder builder) {
this.provideUserProvider = new Factory<User>() {
private final AppComponent appComponent = builder.appComponent;
@Override public User get() {
User provided = appComponent.provideUser();
if (provided == null) {
throw new NullPointerException("Cannot return null from a [email protected] component method");
}
return provided;
}
};
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUserProvider);
}
// 注入
@Override
public void inject(MainActivity activity) {
mainActivityMembersInjector.injectMembers(activity);
}
// 最重要的Builder,构建者
public static final class Builder {
private ActivityModule activityModule;
private AppComponent appComponent;
private Builder() {
}
// 返回ActivityComponent对象。
// 同时,在构造函数中传入Builder对象。
public ActivityComponent build() {
if (activityModule == null) {
throw new IllegalStateException("activityModule must be set");
}
if (appComponent == null) {
throw new IllegalStateException("appComponent must be set");
}
return new DaggerActivityComponent(this);
}
// 传入的ActivityModule参数
public Builder activityModule(ActivityModule activityModule) {
if (activityModule == null) {
throw new NullPointerException("activityModule");
}
this.activityModule = activityModule;
return this;
}
// ................
}
}边栏推荐
- Milliards de données pour déterminer si un élément existe
- 单片机:Modbus 通信协议介绍
- leetcode. 1 --- sum of two numbers
- 【LeetCode】860. Change with lemonade (2 brushes for wrong questions)
- 单片机:A/D 差分输入信号
- 5G China unicom 直放站 网管协议 实时性要求
- 单片机:NEC 协议红外遥控器
- Lambda termination operation find and match nonematch
- Lambda end operation find and match allmatch
- Common encryption and decryption function encapsulation - AES encryption and decryption
猜你喜欢

Dumi construit un blog documentaire

R: Airline customer value analysis practice

120. 三角形最小路径和-动态规划

Differences and relations between three-tier architecture and MVC

Manage PC startup items

10 minutes to thoroughly understand how to configure sub domain names to deploy multiple projects

Goframe day 5

Promise combined with await
![[笔记]vs2015 编写汇编masm32之使用MASM32库](/img/f5/b47336af248d1b485208ec3f9ca12b.png)
[笔记]vs2015 编写汇编masm32之使用MASM32库
![[kubernetes series] pod chapter actual operation](/img/ac/fb563f3d92e6fdbd36e41d2f213556.jpg)
[kubernetes series] pod chapter actual operation
随机推荐
Unity shader learning 004 shader debugging platform difference third-party debugging tools
Sword finger offer II 022 Entry node of a link in a linked list
Lambda termination operation find and match nonematch
单片机:A/D 和 D/A 的基本概念
Value of line height
[kubernetes series] pod chapter actual operation
Single chip microcomputer: basic concepts of a/d and d/a
try-catch finally执行顺序的例题
高等数学(第七版)同济大学 习题1-3 个人解答
Zoom and move the H5 part of the mobile end
Discussion sur la modélisation de la série 143
Detailed explanation of KOA development process
Configuration and practice of shardingsphere JDBC sub database separation of read and write
Hugo 博客搭建教程
Lambda end operation find and match findany
Principle, composition and functions of sensors of Dajiang UAV flight control system
Call C function in Lua
Data analysis report
Student management system
Ego planner code analysis ----cmakelists Txt and package xml