版权声明:本文为申然哥哥原创文章。原文链接:http://blog.csdn.net/qq_27778869/article/details/52121208
通过这几天对这三者开发中的使用,今天准备做一个小的总结,帮助需要爬坑的"道友"!
1.## 首先先分别介绍一下这三个是什么东东 ##
1.MVP:MVP是基于MVC的改进,相信大家都是从MVC走过的,可能很多人还会在项目中使用MVC,我们传统的MVC 中xml布局充当就是视图层(View) ,业务层兼模型层的一些业务的处理需要在我们Activity 或Fragment中进行处理然后更新视图层,由于xml定义好的布局,一旦加载之后,只能通过动态更新,那么视图层和Model就建立了联系,因此二者的耦合度就提高了,那么一旦修改了其中的一个就有可能对另一产生影响,这很不利于我们后期的项目维护。同时所有的操作在我们的Controller中进行处理,我们的Controller就会显得十分的臃肿,可阅读性就降低了,对我们后期的项目维护成本提高了不少,很多时候你需要和团队一起开发一个项目,如果你的同事有一天在你请假或者想修改功能的时候发现一个Activity都有上前行甚至更多的时候,他开始慌了,他慌的时候如果还找到你的话,你可能也慌了。有了MVP之后,妈妈再也不用担心我会慌了!
## 我们的MVP模式来了 ##在MVP中model层依然不变,只不过之前充当Controller的Activity或者Fragment就变身为了View层,而业务逻辑的实现是在我们的Presenter中。简单介绍完了MVP,光说不练,一点效果都没有的,下面我们来进行MVP的三部曲:
本次案例是在进入程序的时候访问服务器的指定接口来获取当前服务器的apk的版本号,通过对比和当前应用程序的版本号,如果有新版本弹出一个土司提示用户更新,功能就这么简单,下面开始码代码:
1.视图层需要哪些更新UI的操作?可能大家会好奇我为什么会问这个,这里我留下一个悬念,待会给大家细讲。这个问题的答案是弹出一个土司提示用户更新。
2.怎么进行更新UI前的操作?
3.何时告知视图层进行UI更新?
结合上面的三个问题:我们根据需求设计代码:
1>定义一个MvpView的接口
public Interface MvpView {
void showMessage();
}
2>定义一个Model类
public class MvpModel{
private String newApkVersion;
public static final String GET_NEW_VER_URL="http://192.168.1:8080/app/index/type?version=query";
public String getNewApkVersion() {
return newApkVersion;
}
public void setNewApkVersion(String newApkVersion) {
this.newApkVersion = newApkVersion;
}
3>定义一个基类BasePresenter(当然大家也可以不用这么做)
public abstract class BasePresenter<T> {
public T mView ;
public void attach(T mView){
this.mView=mView;
}
public void dettach(){
mView=null;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
4>定义一个实际操作的MvpPresenter
public class MvpPresenter extends BasePresenter<MvpView> {
private MvpModel mMvpModel;
private Context mContext;
private RequestQueue mRequestQueue;
public MvpPresenter (Context mContext) {
this.mContext = mContext;
mRequestQueue = VolleyManager.getInstance(mContext).getRequestQueue();
mUpdateModel = new MvpModel();
}
public void onResume(){
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
5>开始视图层的构建了不过在之前我们先创建一个BaseMvpActivity 用于统一化管理我们的MVP模式的Activity的构建
public abstract class BaseMvpActivity<V,T extends BasePresenter<V> > extends AppCompatActivity {
public T presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter=initPresenter();
}
@Override
protected void onResume() {
super.onResume();
presenter.attach((V)this);
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.dettach();
}
public abstract T initPresenter();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
6>正式写我们的应用Activity了(当前activity的布局中仅有一个TextView)
public class MvpActivity extends BaseMvpActivity<MvpView,MvpPresenter> implements MvpView{
@Bind(R.id.tvShow)
TextView tvMsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
ButterKnife.bind(this);
}
@Override
protected void onResume() {
super.onResume();
presenter.onResume();
}
@Override
public MvpPresenter initPresenter() {
return new MvpPresenter (getApplicationContext());
}
@Override
public void showMessage(){
tvMsg.setText("有新版本需更新!");
Toast.makeText(getApplicationContext(),"更新版本啦",Toast.LENGTH_LONG).show();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
7>看到上面的MvpActivity 是不是觉得代码很清爽,那还不是把业务处理的逻辑丢给了 Presenter了,好了我们来具体看看MvpPresenter是怎么写
pulic void onResume(){
getVerFromServer();
}
private void getVerFromServer(){
JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.GET, MvpModel.GET_NEW_VERSION ,null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.e("请求版本返回结果为:",response.toString());
try {
mUpdateModel.setNewApkVersion(response.getJSONObject("data").getString("version"));
if(mUpdateModel.getNewApkVersion.equals(getCurrentVer())){
mView.showMessage();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
jsonRequest.setTag("getVer");
mRequestQueue.add(jsonRequest);
}
private String getCurrentVer(){
String verName="";
try {
verName=mContext.getPackageManager().getPackageInfo(context.getPackageName(),0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
Log.e("apkVer",verName);
return verName;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
2.##Retrofit的简单使用介绍 ##
相信大家在开发过程中被这个字眼给冲击过不少次,具体Retrofit 是什么这里我就不详细介绍了,如果有不明白的读者可以看看我之前的一篇的文章对Retrofit有简单的介绍,但是这里我们只针对它的简单应用来讲解:
1>我们首先需要创建一个接口如RetrofitCall,因为Retrofit是通过注解的形式构建方法的 下面我们来 写一下:
public interface RetrofitCall{
@GET("app/index/type")
Call<VersionBean> getVer(@Query(version) String ver);
}
2>注册网络访问(这里的代码是在Presenter实现的)
Retrofit mRetrofit =new Retrofit.Builder()
//这里为主机加端口(或域名)
.baseUrl("http://192.168.1:8080/")
.clent(new OkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build()
3>创建自定义接口实例并执行异步网络请求
RetrofitCall call=mRetrofit.create(RetrofitCall.class);
Call<VersionBean> myCall=call.getVer("1");
maCall.enqueue(new Callback<VersionBean>(){
@Override
public void onResposne(Call<VersionBean>call,retrofit2.Response<VersionBean> response) {
if(response.body().getData().getVersion().equals(getCurrentVe r())){
mView.showMessage();
}
}
@Override
public void onFailure(Call<VersionBean> call, Throwable t) {
Log.e("callerro+"------------>"+t);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
3.## 通过RxJava对上面Retrofit 的改进 ##
RxJava 是一个异步操作的库,主要采用的观察者模式,在这里我只是简单的介绍,需要详细了解可以参考扔物线的这篇[给Android开发工程师的一篇关于RxJava的详解](http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/1012/3572.html?from=timeline&isappinstalled=0#toc_1)
在这里我就不作过多的篇幅来介绍了,我们来演示RxJava依靠Retrofit的改进上面的代码,我们在RetrofitCall中添加一个新的注解
@GET("app/index/type")
Observable<VersionBean> getVerByRxJavaWithRetrofit(@Query("version") String ver);
接着在Presenter中填入如下的方法:
private void requestDataByRxJavaWithRetrofit(){
Retrofit mRxjavaRetrofit= new Retrofit.Builder()
.baseUrl("http://192.168.1:8080/")
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitCall call= mRxjavaRetrofit.create(RetrofitCall.class);
call.getVerByRxJavaWithRetrofit(""1)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(new Observer<Version>(){
@Override
public void onCompleted() {
mView.showMessage();
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(LogoBean logoBean) {
}
} );
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
4## 总结 ##
上面对这三者的结合使用有了一个直观的介绍,其实MVP模式可以理解为 更新UI需要什么操作,什么时候开始更新UI,怎么更新UI;而我们的MVP模式就是把这三种状态巧妙地分开,因此会让思路显得很清晰,而RxJava 正式基于这种设计,被观察者通过被订阅的形式在自己有新动态的时候告知观察者我改变了,剩下的就交给观察者做自己应该做的事情了!这样的设计模式很符合我们需求,也很利于团队开发,换个模式你会觉得效率大大提高,让我们一起加入MVP+RxJava+Retrofit的队列之中吧!