Dagger入门及MVP
Dagger 是一个依赖注入框架,简称DI,如果用过spring,就会很清楚依赖注入,因为Spring 的核心思想就是依赖注入,不论是Action 对象,还是Service 对象,还是DAO对象,都可以在spring的管理下协调的运行。
那么啥是依赖注入呢?
对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用,传递给它。也可以说,依赖被注入到对象中。也就是说,被注入的对象不需要重复的初始化就可以获得相应的引用, 这段概念不太好懂,简单的说就是目标类中所依赖的其他的类的初始化过程,不是通过手动编码的方式创建,而是通过技术手段可以把其他的类的已经初始化好的实例自动注入到目标类中。说简单就是一次构建,到处注入。
Dagger2
Dagger2 是Dagger1 的分支,目前由google公司开发.Dagger2收到AutoValue的启发,Dagger是依赖注入的一种。
Dagger2 的好处
这一点在 github
Dagger 基本组成
- @Inject : 通常在需要依赖的地方使用这个注解,用它告诉Dagger某个类或者字段需要依赖注入,这样Dagger 会构造一个这个类的实例并且满足他们的依赖。
@Module : Modules 类里面的方法专门提供依赖,所以定义一个类 ,用@Module 注解,这样Dagger 在构造类的实例的时候,就知道从哪里去找到需要的依赖,modules 的一个重要特征是他们设计位分区并组合在一起。
- @Provide : 在Modules中,定义的方法是用这个注解,以此来告诉Dagger 想要构造对象并提供依赖
- @Component : Components 根本上说是一个注入器,可以说是@Inject 和 @Module桥梁,主要作用用于连接两部分。
Dagger2 简单入门
- 引入Dagger
根目录build.gradle 引入apt
所在module 的build.gradle 配置
首先引入 apt
apply plugin: 'com.neenbedankt.android-apt'
引入依赖
dependencies {
//java注解
provided 'javax.annotation:javax.annotation-api:1.2'
//dagger2
compile 'com.google.dagger:dagger:2.5'
//dagger编译器
apt 'com.google.dagger:dagger-compiler:2.5'
}
- 示例 把User对象的值赋值到Activity中 代码结构如下:
User类
public class User {
public String getName() {
return name;
}
public User(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
private String name;
private String pwd;
}
UserModule 类
@Module //标识提供依赖
public class UserModule {
@Provides //所构造的对象并提供依赖
User providerUser(){
return new User("username","mimi");
}
}
UserComonent 类
@Component(modules = UserModule.class)
public interface UserComponent {
void inject(DaggerActivity activity);
}
因为 UserComonent 是一个接口文件,无法直接使用,需要借助Dagger生成注解对象。
之后会在app/build/generated/source/apt/debug 目录下生成 DaggerUserComponment,当然我们用到的目前是Dagger开头的Componment文件,这时可以在Activity完成注入
DaggerActivity
public class DaggerActivity extends AppCompatActivity {
@Inject
User user;
private TextView textView;
UserComponent userComponent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dagger);
textView = (TextView) findViewById(R.id.tv_text);
userComponent = DaggerUserComponent.builder().build();
userComponent.inject(this);
textView.setText(user.getName() + ":" + user.getPwd());
}
}
运行结果
Dagger 与MVP 结合 接下来结合MVP 做一个简单使用例子。
可以看到,在mvp 结构之上增加了 module 与 componment. 与mvp 的结合主要在对presenter的改造上,完成对Presenter 的注入。 本示例为模拟登录的例子,model 完成登录判断逻辑,presenter 完成对view 控制,module 完成对presenter 注入提供依赖,componment 协调被注入activity 与module 关系。
ILoginView
public interface ILoginView {
void showLoding();
void hidLoding();
void showSuccess();
interface LoginListener {
void onSuccess();
void onError(String msg);
}
}
UserModel
public void login(final String name , final String password, final ILoginView.LoginListener listener) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if(checkParams(name,password)){
listener.onSuccess();
} else {
listener.onError("用户密码错误");
}
}
},3000);
}
public boolean checkParams(String name, String pwd) {
return true;
}
}
UserPresenterModule
@Module
public class UserPresenterModule {
private ILoginView loginView;
public UserPresenterModule(ILoginView iLoginView){
this.loginView = iLoginView;
}
@Provides
ILoginView provideLoginView(){
return loginView;
}
@Provides
UserPresenter provideUserPresenterModule (ILoginView loginView){
return new UserPresenter(loginView);
}
@Provides //所构造的对象并提供依赖
User providerUser(){
return new User("username","mimi");
}
}
LoginComponent
@Component(modules = UserPresenterModule.class)
public interface LoginComponent {
void inject(MainActivity activity);
}
MainActivity
public class MainActivity extends AppCompatActivity implements ILoginView {
@Inject
User user;
// UserComponent component;
LoginComponent loginComponent;
@Inject
UserPresenter userPresenter;
private AppCompatEditText edit_user;
private AppCompatEditText edit_pwd;
private AppCompatButton btn_login;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit_user = (AppCompatEditText) findViewById(R.id.edit_username);
edit_pwd = (AppCompatEditText) findViewById(R.id.edit_password);
btn_login = (AppCompatButton) findViewById(R.id.btn_login);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
login("username","password");
}
});
// component = DaggerUserComponent.builder().build();
// component.inject(this);
loginComponent = DaggerLoginComponent.builder().userPresenterModule(new UserPresenterModule(this)).build();
loginComponent.inject(this);
Log.i("MainActivirty", "onCreate: " + user.getName());
}
public void login(String username , String password) {
userPresenter.login(username,password);
}
@Override
public void showLoding() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void hidLoding() {
progressBar.setVisibility(View.GONE);
}
@Override
public void showSuccess() {
Toast.makeText(this,"success",Toast.LENGTH_SHORT).show();
}
}
示例图