MVP+Okhttp3+Retrofit2+Rxjava2 框架实现

一、MVP

简称:MVP 全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。(from 百度)

MVP模式_百度百科:https://baike.baidu.com/item/MVP%E6%A8%A1%E5%BC%8F/10961746?fr=aladdin

MVC造成的问题:①View 层和 Controller 层没有分离,逻辑混乱;②View 和 Controller 层的耦合,导致 Activity 或者 Fragment 臃肿,代码量很大。因此为了解决以上问题,我们使用MVP模式

参考文章:https://upload-images.jianshu.io/upload_images/3013099-4008dabb029fa246.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

当 View 需要更新数据时,通过 Presenter 去找 Model 请求数据,Model 获取到数据后通知 Presenter,Presenter 再通知 View 更新数据,使得 Model 和 View 不会直接交互,所有的交互都由 Presenter 进行,Presenter 充当了桥梁的角色。很显然,Presenter 必须同时持有 View 和 Model 的对象的引用,才能在它们之间进行通信。

参考文章:https://blog.csdn.net/singwhatiwanna/article/details/80841705

二、Okhttp3
参考文章:https://www.jianshu.com/p/9f2c982cd500

Square公司的一款开源的网络请求库
工作流程:通过OkHttpClient将构建的Request转换为Call,然后在RealCall中进行异步或同步任务,最后通过一些的拦截器interceptor发出网络请求和得到返回的response。

依赖库:

//网络请求okhttp3
compile'com.squareup.okhttp3:okhttp:3.9.1'
//日志的拦截器
compile'com.squareup.okhttp3:logging-interceptor:3.6.0'

三、Retrofit2

Square公司开发的一款针对Android 网络请求的框架(底层默认是基于OkHttp 实现)。

依赖库

    //Retrofit2库
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    //gson解析
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0

四、Rxjava2
一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库),RxJava使异步操作变得非常简单。

   //rxjava2库
    compile 'io.reactivex.rxjava2:rxjava:2.0.1'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

基本了解了几个开源框架后,我们进入实战,看到我的项目结构:


项目结构图

第一步:新建mode类

拿到需要请求的API数据,粘贴API到谷歌浏览器回车查看数据,jsonhandle插件自动格式化数据
json数据

创建数据的model类
AppVersionModel.java

Retrofit2基于Gson解析,尽量把数据中的每个字段都描述到,model类增加构造方法、getter/setter方法、toString方法。

第二步:初始化Retrofit
新建RetrofitHelper.java。用于初始化Retrofit,设置请求API的baseUrl、gson解析方式


RetrofitHelper.java

新建RetrofitService.java。管理Retrofit的各种数据请求(post、get),包含请求api、请求参数。


RetrofitService.java

注意:post请求中必须增加注解@FormUrlEncoded,否则会报异常。

第三步:View的接口类

public interface AppVersionView extends View{
    void onSuccess(AppVersionModel appVersion);
    void onError(String error);
}

第四步:Presenter的接口类

/**
 * Created by wuhuihui on 2019/5/17.
 * Presenter:基类方法用于Activity或Fragment在onDestory解绑View
 * 所有presenter的基类,子类实现其方法,
 */
public interface Presenter {
    void onCreate();
    void onStart();
    void onDestory();
    void pause();
    void attachView(View view);
    void attachIncomingIntent(Intent intent);
}

对于请求的实现Presenter类

class AppVersionPresenter implements Presenter
 @Override
    public void onCreate() {
        manager = new DataManager(context);
        compositeDisposable = new CompositeDisposable();
        //RxJava1: mCompositeSubscription = new CompositeSubscription();
    }

    @Override
    public void onDestory() {
        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
            compositeDisposable.dispose(); //解除订阅
            compositeDisposable.clear(); //取消所有订阅
            compositeDisposable = null;
            //RxJava1:CompositeSubscription.unsubscribe();
        }
    }

网络请求封装

 public void getAppVersion(String currentVersion, String type) {
        Observable<AppVersionModel> observable = manager.getAppVersion(currentVersion, type);
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<AppVersionModel>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(AppVersionModel value) {
                        appVersion = value;
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        Log.i(TAG, "onError:" + e.toString());
                        appVersionView.onError("请求失败:\n" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.i(TAG, "onComplete!");
                        if (appVersionView != null) {
                            appVersionView.onSuccess(appVersion);
                            Log.i(TAG, "appVersion:" + appVersion.toString());
                        }
                    }
                });
    }

第五步:DataManager:数据处理管理器,用于处理多个API Observable

/**
 * Created by wuhuihui on 2019/5/17.
 * DataManager:数据处理管理器,用于处理多个API Observable
 */
public class DataManager {
    private RetrofitService retrofitService;
    public DataManager(Context context) {
        this.retrofitService = RetrofitHelper.getInstance(context).getServer();
    }
    public Observable<AppVersionModel> getAppVersion(String currentVersion, String type) {
        return retrofitService.getAppVersion(currentVersion, type);
    }
}

第六步:网络请求实现并显示数据 MainActivity.java
MainActivity的布局中放两个控件, Button requestData点击按钮实现网络请求,TextView showData用来显示数据。

private AppVersionPresenter appVersionPresenter = new AppVersionPresenter(this);

appVersionPresenter.getAppVersion("6.0", "android"); //开始请求数据
appVersionPresenter.onCreate(); //启动Presenter,订阅View
        //刷新UI,显示数据
        appVersionPresenter.attachView(new AppVersionView() {
            @Override
            public void onSuccess(AppVersionModel appVersion) {
                showData.setText(appVersion.getLatestVersion()
                        + "\n" + appVersion.getSize()
                        + "\n" + appVersion.getUrl()
                        + "\n\n新版本更新内容:\n"
                );

                List<String> list = appVersion.getFunctions();
                for (int i = 0; i < list.size(); i++) {
                    showData.append(list.get(i) + "\n");
                }
            }

            @Override
            public void onError(String error) {
                showData.setText(error);
            }
        });
//当activity onDestroy时取消对View的引用
 @Override
    protected void onDestroy() {
        super.onDestroy();
        appVersionPresenter.onDestory(); //取消view的引用,避免内存泄漏
    }

运行结果:


显示数据

大概的代码实现已经讲完,基本的框架思路已经成型。
最后附上gitHub地址:https://github.com/wuhuihui2016/InitMVP.git
应该庆幸有这么一段待业期,让我重新认识自己,重新审视自己的傲娇,至少能够认识到自己的不足并及时补救,就为时未晚。任重而道远,加油,还有更多技术、框架值得去深究,保持学习的心态,学到老活到老。学习不是浅尝辄止,每一次都应该用心实现,善始善终。
每天进步一点点,技术分享还在更新。。。
路过的大神们,希望对你们有帮助,同时如果有更好的见解和意见,请多多评论指正,也期待得到您的喜欢与支持~~~ (190517)
上一篇:Android XMPP实现即时通讯:https://www.jianshu.com/p/f0cef68eb9ac
下一篇:OKHttp LoggingInterceptor的使用:https://www.jianshu.com/p/53a9125d610d
我的更多学习分享:https://www.jianshu.com/u/57ab9a74e2c0

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343