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

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

目前流行的开发模式,以我目前的所能接触到的知识面,在我眼中应该是
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的小架子,自己的思路,有好建议,请指出,多谢!!!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值