Android MVP+Dagger2使用教程
来源:互联网 发布:华为光猫开启端口23 编辑:程序博客网 时间:2024/06/01 10:21
Dagger2是一个依赖注入框架,在解耦合方面堪称强大。如果你还不知道什么是依赖注入,以及使用Dagger2的原因,那么还是麻烦你先去google、百度一下,这里我暂时不会涉及dagger2的原理,而是使用一个非常简单的MVP例子来应用dagger2。为什么要使用MVP的例子讲解呢?因为dagger2和MVP是天造地设的一对~、
一、不使用dagger2的MVP Demo
这个MVP Demo非常简单,模拟手机号码归属地查询的实现。如下图,在EditText中输入手机号码,点击查询按钮,就会显示出手机号码所归属的省市。PS:为了简(偷)便(懒),这里并不存在网络请求,我只是模拟了这一过程而已,所以手机号输入可以是随意的字符即可,只要保证EditText的内容不为空就可以了,各位见怪勿怪哈哈哈~
MVP分为model、view、和presenter,其中Activity承担View的角色,只负责控件的显示和更新。model负责业务逻辑和各种数据实体,presenter则负责连接Activity。
1、View
首先是IQueryView.java
public interface IQueryView { //查询成功后,显示手机归属地的查询结果 void showSuccessMsg(String successMsg); //查询失败,显示失败原因 void showErrorMsg(String errorMsg);}
然后在MainActivity中实现该接口:
MainActivity.class
public class MainActivity extends AppCompatActivity implements IQueryView,View.OnClickListener{ //输入手机号码 EditText et; //显示查询结果 TextView tv; Button btn; //presenter的实现在下面 public QueryPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et= (EditText) findViewById(R.id.et); tv= (TextView) findViewById(R.id.tv_res); btn= (Button) findViewById(R.id.btn_query); presenter=new QueryPresenter(this); btn.setOnClickListener(this); } //在TextView中显示查询结果,Activity只负责View的更新和显示 @Override public void showSuccessMsg(String successMsg) { tv.setText(successMsg); } //查询失败时,Toast提示 @Override public void showErrorMsg(String errorMsg) { Toast.makeText(this,errorMsg,Toast.LENGTH_LONG).show(); } //点击查询按钮时,将查询逻辑交给Presenter @Override public void onClick(View view) { presenter.query(et.getText().toString().trim()); }}
2、Presenter
Presenter负责连接view和model,view无法直接获取model的数据,model也无法直接操作view,即实现了view和model之间的完全解耦。Presenter和View、Presenter和Model之间的通信都是使用接口。
QueryPresenter.java:
public class QueryPresenter implements OnQueryListener{ private IQueryView view; public QueryModel model; public QueryPresenter(IQueryView view){ this.view=view; model=new Model(); } //使用model发起网络请求 public void query(String phoneNumber){ model.queryNumber(phoneNumber,this); } @Override public void onSuccess(String successMsg) { //通知View更新 view.showSuccessMsg(successMsg); } @Override public void onError(String errorMsg) { view.showErrorMsg(errorMsg); }}
onQueryListener.java:连接Presenter和Model
public interface OnQueryListener { //model通知presenter查询成功 void onSuccess(String successMsg); //model通知presenter查询失败 void onError(String errorMsg);}
3、Model
model代表业务逻辑和数据实体,在这里,model完成手机号归属地查询的网络请求(模拟)
QueryModel.java:
public class QueryModel { public QueryModel(){} /** * 模拟手机号码归属地查询 * @param phoneNum * @param listener */ public void queryNumber(String phoneNum, OnQueryListener listener){ //模拟网络请求,请求结果为广东 东莞 String result="广东 东莞"; //通知Presenter listener.onSuccess(result); }}
好了,完整的MVP Demo就是这样了。可以看到,我们在MainActivity中需要实例化Presenter:
presenter=new QueryPresenter(this);
在QueryPresenter中我们还需要实例化Model
public QueryPresenter(IQueryView view){ this.view=view; model=new Model(); }
这就是所谓的依赖,MainActivity依赖QueryPresenter,QueryPresenter依赖QueryModel。在大型项目中,一个类可能依赖多个其他的类,需要书写类似A a=new A( )的代码就会很多很繁琐,而使用dagger2就可以省去很多代码量,更重要的是,降低耦合度,让程序结构更清晰,易于维护和测试。
二、使用dagger2的MVP Demo
1、引入dagger2的准备工作
在project–build.gradle中添加apt插件。PS:apt插件不止这一种
build.gradle:
// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.3' //添加apt插件 classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files }}allprojects { repositories { jcenter() }}task clean(type: Delete) { delete rootProject.buildDir}
在app–build.gradle中添加依赖,记得在上方添加:
apply plugin: 'com.neenbedankt.android-apt'
app-build.gradle:
apply plugin: 'com.neenbedankt.android-apt'....dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' testCompile 'junit:junit:4.12' //dagger2和Java注解的依赖 compile 'com.google.dagger:dagger:2.11' compile 'org.glassfish.main:javax.annotation:4.0-b33' //注意是apt而不是compile apt 'com.google.dagger:dagger-compiler:2.11'}
好了,准备工作做好了,可以开始使用dagger2了
2、应用dagger2
首先在需要被实例化的依赖对象的构造函数中添加注解@inject
先举个简单的例子吧,QueryModel的构造函数不需要参数,也就是默认的无参构造函数:
@Inject public QueryModel(){}
然后在需要用到QueryModel的类QueryPresenter中也添加@inject注解(在对象声明处添加)
@Inject public QueryModel model;
在这两个地方都添加了@inject依赖就意味着告诉dagger,我这个model对象是需要实例化的,当用到model时,你就使用被@inject的构造函数来实例化这个model吧
那现在问题是谁来实例化这个对象?于是就轮到Component出来了:
QueryPresenterComponent.java:
@Componentpublic interface QueryPresenterComponent { void inject(QueryPresenter presenter);}
注意上方的@Component注解,其中的inject()方法表明该Component是可以为QueryPresenter进行依赖注入的。还要注意一点,该类必须是抽象类或者接口,
最后,我们需要在Presenter中实时地声明对类对象进行依赖注入,原本的model=new QueryModel( )就不需要了。
注意:我们使用了DaggerQueryPresenterComponent,这个类是Dagger2自动为我们生成的,命名规则是在我们刚刚创建的类QueryPresenterComponent前面加上Dagger。在make project之后我们才能使用这个类。
public QueryPresenter(IQueryView view){ this.view=view; //model=new QueryModel(); DaggerQueryPresenterComponent.builder().build().inject(this); }
好了,修改完毕后重新运行程序,运行结果是一样的。
现在有个问题就是QueryPresneter的实例化,也就是在MainActivity中的依赖注入。这时候操作基本和上面差不多,但是要发现的一点是QueryPresneter的构造函数是需要一个参数的:
public QueryPresenter(IQueryView view){ this.view=view; DaggerQueryPresenterComponent.builder().build().inject(this); }
来,我们一步一步来
首先,还是添加@inject
在QueryPresenter构造函数和MainActivity对象声明处添加注解:
@Inject public QueryPresenter(IQueryView view){ this.view=view; DaggerQueryPresenterComponent.builder().build().inject(this); }
@Inject public QueryPresenter presenter;
然后就是创建Component了,但是这次稍有不同,在创建Component之前我们先创建Module
Module你可以理解为对象提供参数。Component能为对象选定构造函数然后创建对象实例,那构造函数中需要的参数呢?就要由Module来提供了
MainActivityModule.class:
@Modulepublic class MainActivityModule { private IQueryView view; //参数通过构造函数传入 public MainActivityModule(IQueryView view){ this.view=view; } //提供参数 @Provides public IQueryView provideQueryView(){ return view; }}
注意上方的@Module注解
我们在MainActivityModule的构造函数中传入QueryPresenter所需要的参数
然后使用@Provides注解注明provideQueryView()适用于提供参数的。
当Component找到以下被@inject的构造方法时,会发现凭借自己无法提供IQueryView 参数,然后就会前往它所关联的Module看其能否提供参数,那么接下来就是把Component和Module进行关联了
@Inject public QueryPresenter(IQueryView view){ this.view=view; DaggerQueryPresenterComponent.builder().build().inject(this); }
再然后,创建Component并关联Module
Component的命名规则一般是:谁需要依赖注入,就在谁的名字后面添加Component,像MainActivity需要注入QueryPresenter,那么在类名就是MainActivityComponent了。
@Component(modules=MainActivityModule.class)public interface MainActivityComponent { void inject(MainActivity activity);}
注意上方的@Component(modules=MainActivityModule.class)
最后,就是在MainActivity中,显示声明依赖注入了,记得先make project
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et= (EditText) findViewById(R.id.et); tv= (TextView) findViewById(R.id.tv_res); btn= (Button) findViewById(R.id.btn_query); btn.setOnClickListener(this);// presenter=new QueryPresenter(this); DaggerMainActivityComponent.builder().mainActivityModule(new MainActivityModule(this)).build().inject(this); }
好了,完整流程就是这样啦,最后附上源码
源码下载
- Android MVP+Dagger2使用教程
- android:mvp+dagger2解析
- Android MVP 使用教程
- android dagger2搭建mvp架构
- Dagger2-android (不是dagger2)使用
- Dagger2使用教程
- Dagger2使用教程
- Dagger2+MVP
- Dagger2+mvp
- Android Dagger2+MVP+Retrofit2 开发案例
- Rxjava + retrofit + dagger2 + mvp搭建Android框架
- Android Dagger2 MVP架构 一看就明白
- Android最流行框架MVP,Dagger2,RxJava
- 【Android - 框架】之Dagger2+MVP的用法
- Android Dagger2 MVP架构 一看就明白
- Android Dagger2 MVP架构 一看就明白
- Dagger2-深入三(mvp结合使用)
- 在kotlin-MVP使用dagger2(v2.11+)
- Smarty模板引擎总结二
- 当子进程结束的时候,其设置的信号捕捉函数不会再父进程生效
- Java中int和Integer的区别
- 本机连接Kafka超时错误信息的解决办法
- cygwin git 在github创建仓库
- Android MVP+Dagger2使用教程
- 挑战程序竞赛系列(11):2.5最短路径
- 稀疏矩阵
- 定位 js解读顺序
- URAL
- 无向图 c语言 (数据结构)
- hardoop 入门
- 支持向量机(一)
- c++远征之模板篇——友元函数、友元类