MVP、泛型、Rxjava---简单封装

来源:互联网 发布:sql数据修复 编辑:程序博客网 时间:2024/04/29 12:24

安卓开发逐步走向标准化,规范化,一个合格的安卓程序员,应该要有代码强迫症,哪些臃肿的代码结构,需要想方设法去优化改变,我本菜鸟,只能一步步去远离菜鸟,我非大神,只能一步步模仿大神

目前流行的开发模式,以我目前的所能接触到的知识面,在我眼中应该是
MVP(因此安卓中这个说的比较多)
注解(Android Annotations、ButterKnife我一般不用,我还是喜欢findViewById)
异步框架(Rxjava最近说的比较多)
混合开发(原生,混合谁也取代不了谁,各取所长)
Retrofit(网络单拎出来)
。。。
。。。
未来还会有更好的

在了解今天的小框架学习中,你可以先去了解了解其他的内容

MVP本质上就是一个Proxy静态代理模式—so easy

RxJava响应式编程之初级了解

Volley、OkHttp、Retrofit+Rxjava总结
这里写图片描述

今天我们就来简单的了解下,如何搭建一个简单的mvp小项目框架
本博文代码,免积分下载!!!免积分下载!!!

我们的需求很简单,看如下截图即可
这里写图片描述

需求是:点击从上到下的第二个Button控件,在第一个TextView控件上显示App版本号

首先看我们需要依赖的东东

dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:23.4.0'    compile 'com.android.support:support-v4:23.4.0'    compile 'com.squareup.retrofit2:retrofit:2.1.0'    compile 'com.google.code.gson:gson:2.6.2'    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'    compile 'io.reactivex:rxjava:1.1.6'    compile 'io.reactivex:rxandroid:1.2.1'    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'}

我这个小例子还得需要,我用的是jdk1.7的,不知道1.8的是不是就没有这个问题

 multiDexEnabled true

什么是MVP?
M就是model数据层,就是承载数据的实体
V就是view界面层,就是展示数据的
P就是Presenter(百度翻译为提出者; 赠送者)就是从Model中获取数据并提供给View的层

需求是:点击从上到下的第二个Button控件,在第一个TextView控件上显示App版本号
牛逼的程序员,都是设计模式、泛型、接口用的很溜的,我们也试着尽可能的模仿牛人的代码
我们该如何去层层剥离代码呢?
MVP其实没有想的那么高端,最简单的MVP的思路就是
就拿我们这个例子来说,V层就是去获取P层提供的数据(我们这里就是获取一个VersionCode),在调用自己的方法,去显示即可

先拿View层来说把:
首先View层自身得有一个方法,去展现获取到的VersionCode,其实在一个APP中,可以根据业务逻辑,抽取共同的View层方法,本例就不抽取了 ,但是预留了一个空接口,ok,那么我们就先看看View层的最最基本的接口对象

BaseView

package com.safly.base;public interface BaseView {}

好吧,那么继续我们就来构造本例中的View层MainViewImpl

package com.safly.ui.inner;import com.safly.base.BaseView;public interface MainViewImpl extends BaseView {    void setAppVersion(int appVersion);}

MainViewImpl很简单嘛,就是接收一个P层获取的数据的传入,然后在展现界面即可

最后的View层是MainActivity这里先不说,先来分析下P层
P层同样是一样的,需要获取AppVersionCode供给View层使用

MainPresenterImpl

package com.safly.presenter.inter;public interface MainPresenterImpl {    public void getAppVersion();}

至此V层P层最基本的方法就构造完毕了,接下来就去完事如何将V层P层,进行连接起来
还拿我们这个例子说,点击Button,就去调用P层的getAppVersion方法,获取数据完毕,就调用V层的setAppVersion方法,所以说P层得需要持有V层的引用,这是必须要做的事

BasePresenter

package com.safly.base;public class BasePresenter<V extends BaseView>{    public V view;    public void bindView(V view){        this.view = view;    }    public void unBindView(){        this.view = null;    }    public boolean checkBindView(){        return view == null;    }}

由于一个app是有好多View界面的,所以我们不能去写更多的P层,我们需要抽取一个基类,这就是引入了泛型 V extends BaseView

那么接下来我们就去看看最后的P是如何写的MainPresenter

package com.safly.presenter;import android.content.Context;import com.safly.base.BasePresenter;import com.safly.presenter.inter.MainPresenterImpl;import com.safly.ui.inner.MainViewImpl;import com.safly.utils.AppUtils;public class MainPresenter extends BasePresenter<MainViewImpl> implements MainPresenterImpl{    Context mContext;    public MainPresenter(Context mContext) {    this.mContext = mContext;    }    @Override    public void getAppVersion() {        int versionCode = AppUtils.getVersionCode(mContext);        view.setAppVersion(versionCode);    }}

MainPresenter 持有View层的引用,P调用getAppVersion,然后V层setAppVersion方法即可

在看MainActivity之前我们需要对View层做进一步的抽取,我先贴出代码,然后在做简单分析
BaseActivity

package com.safly.base;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.LayoutInflater;import java.util.zip.Inflater;/** * Created by safly on 2016/11/9. */public abstract  class BaseActivity<V extends BaseView,P extends BasePresenter<V>> extends AppCompatActivity {    public LayoutInflater mInflater;    public P presenter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(getLayouResId());        mInflater = LayoutInflater.from(this);        presenter = initPresenter();        presenter.bindView((V)this);        initRes();        doOtherWork();    }    @Override    protected void onResume() {        super.onResume();        doOnResume();    }    protected abstract void doOnResume();    protected abstract void doOtherWork();    protected abstract P initPresenter();    public abstract int getLayouResId();    protected abstract void initRes();    @Override    protected void onDestroy() {        super.onDestroy();        if (presenter != null){            presenter.unBindView();        }    }}

在上面代码中initPresenter是持有P层的引用,为了去构造不同的View层的P类对象,
presenter.bindView((V)this);是P层绑定V层,便于V层调用本类方法
getLayouResId、initRes、doOtherWork、doOnResume这些就是大家比较熟悉的了,获取布局文件、初始化控件、获取数据操作,onResume等等,你也可以根据项目需要进行进一步扩充

千呼万唤使出来,最后看MainActivity本例的V层

package com.safly.ui;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.safly.R;import com.safly.base.BaseActivity;import com.safly.presenter.MainPresenter;import com.safly.ui.inner.MainViewImpl;import java.util.concurrent.TimeUnit;import rx.Subscriber;import rx.functions.Action1;public class MainActivity extends BaseActivity<MainViewImpl,MainPresenter> implements View.OnClickListener,MainViewImpl{    TextView showAppVersion;    Button showToast;    @Override    public int getLayouResId() {        return R.layout.activity_main;    }    @Override    protected void initRes() {        showAppVersion = (TextView) findViewById(R.id.showAppVersionCode);        showToast = (Button) findViewById(R.id.showToast);        showToast.setOnClickListener(this);    }    @Override    protected MainPresenter initPresenter() {        return new MainPresenter(this);    }    @Override    protected void doOtherWork() {    }    @Override    protected void doOnResume() {    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.showToast:                presenter.getAppVersion();                break;        }    }    @Override    public void setAppVersion(final int appVersion) {        rx.Observable.create(new rx.Observable.OnSubscribe<Integer>() {            @Override            public void call(Subscriber<? super Integer> subscriber) {                subscriber.onNext(appVersion);            }        }).subscribe(new Action1<Integer>() {            @Override            public void call(Integer integer) {                showAppVersion.setText(String.valueOf(integer));            }        });    }    private boolean hasClickBack = false;    @Override    public void onBackPressed() {        if (hasClickBack) {            this.finish();        } else {            hasClickBack = true;            Toast.makeText(this, "再次按退出Demo", Toast.LENGTH_SHORT).show();            rx.Observable.create(new rx.Observable.OnSubscribe<Boolean>() {                @Override                public void call(Subscriber<? super Boolean> subscriber) {                    subscriber.onNext(false);                }            }).delay(3, TimeUnit.SECONDS)                    .subscribe(new Action1<Boolean>() {                        @Override                        public void call(Boolean aBoolean) {                            hasClickBack = aBoolean.booleanValue();                        }                    });        }    }}

现在MainActivity中代码就显得很清晰了,解析来我们就看看Rxjava的简单使用,这里只是简单使用而已

 @Override    public void setAppVersion(final int appVersion) {        rx.Observable.create(new rx.Observable.OnSubscribe<Integer>() {            @Override            public void call(Subscriber<? super Integer> subscriber) {                subscriber.onNext(appVersion);            }        }).subscribe(new Action1<Integer>() {            @Override            public void call(Integer integer) {                showAppVersion.setText(String.valueOf(integer));            }        });    }    private boolean hasClickBack = false;    @Override    public void onBackPressed() {        if (hasClickBack) {            this.finish();        } else {            hasClickBack = true;            Toast.makeText(this, "再次按退出Demo", Toast.LENGTH_SHORT).show();            rx.Observable.create(new rx.Observable.OnSubscribe<Boolean>() {                @Override                public void call(Subscriber<? super Boolean> subscriber) {                    subscriber.onNext(false);                }            }).delay(3, TimeUnit.SECONDS)                    .subscribe(new Action1<Boolean>() {                        @Override                        public void call(Boolean aBoolean) {                            hasClickBack = aBoolean.booleanValue();                        }                    });        }    }

第一个是获取AppVersionCode,然后在View界面上设置数据
第二个是3秒内连续点击会退键退出Demo
我对Rxjava也是简单了解而已,如果你也想着简单了解可以去看看博客开头的几篇博文,Retrofit里面有对Rxjava的封装,还有一篇专门讲Rxjava的

最后SaflyApplication获取全局变量的

package com.safly;import android.app.Application;public class SaflyApplication extends Application {    private static SaflyApplication instance;    @Override    public void onCreate() {        super.onCreate();        SaflyApplication.instance = this;    }    public static SaflyApplication getInstance(){        return SaflyApplication.instance;    }}

以上就是一个简单的MVP的小架子,自己的思路,有好建议,请指出,多谢!!!

1 0