rxjava+retrofit+okhttp+mvp 简单实践

来源:互联网 发布:单片机是嵌入式处理器 编辑:程序博客网 时间:2024/05/22 15:03

好久没写博客了,汗,平时喜欢看博客,却不喜欢写博客,这样不行的,惭愧!

今年进了一家新公司,老大说了,先熟悉代码,等新的UI出来后,重构。所以,这些天,就一直在熟悉代码并开始项目的最基本框架搭建了。

Rxjava,Retrofit,Okhttp,MVP,这些关键字都是去年比较流行的,随便一个技术论坛或者技术博客,都可以看到,如果你或者他,还对这些关键词感觉到陌生的话,恭喜你,你和我一样了,OUT了,o(∩_∩)o 。

还有,学习新东西一定不要着急,一步一步来,看一遍不明白,那么回过头来看第二遍,第三遍…..看的多了,熟悉了,那么就会用了,如果有上进心的话,可以研究源码,想想具体实现原理等。

水平线~~~~

Rxjava知识,推荐扔物线的博客,地址:http://gank.io/post/560e15be2dca930e00da1083 我想说的是,这篇博客我看了不下5遍,刚开始很容易弄晕,后来看着看着就明白了。

Retrofit知识,直接看官方文档,地址:http://square.github.io/retrofit/

Okhttp知识,也直接看官方文档,地址:http://square.github.io/okhttp/

MVP 相关,这里推荐先看下谷歌的官方demo,地址:https://github.com/googlesamples/android-architecture

这里写图片描述

以上截图是官方的demo,MVP,MVVM等都在上面,值得参考。

看完官方的在推荐看下这个博客,地址:http://www.jianshu.com/p/ac51c9b88af3 或者 直接拿Github上现成的 MVPArms,地址:https://github.com/JessYanCoding/MVPArms/wiki

这里写图片描述

好了,我知道的就这么多了~~~~

现在来看下我项目中自己的实践封装,我尽量写详细点,有问题或者觉得不妥的地方都可以给我提意见,互相帮助,才是学习的进步嘛。

先看下项目的配置文件:

这里写图片描述

红色框圈中的部分都是依赖,这点AS确实很方便,想想如果换成Eclipse的话,该有多麻烦啊。事实上,现在AS已经慢慢的成为主流了,虽然我现在看的是14年的项目,它是EC结构的,汗。

依赖添加完成后,再来看下项目的包结构:

这里写图片描述

1.net里放的都是网络请求相关,以及封装okhttp下载监听,上传监听的实现。
2.mvp自然就是View,Presenter,Mode了。
3.util 工具类。
4.view 自定义的view。
5.common 相关通用的东西。

一、网络请求的封装:

网络请求主要看ApiServer.java,RetrofitManager.java,StringObserver.java和BaseObserver.java这四个类即可。

1.ApiServer.java :

    @GET("{url}")    Observable<String> get(@Path("url") String url,                           @QueryMap Map<String, String> maps);    @FormUrlEncoded    @POST("{url}")    Observable<String> post(            @Path("url") String url,            @FieldMap Map<String, String> maps);    @POST("{url}")    Observable<String> post(            @Path("url") String url,            @Body RequestBody body);    @Multipart    @POST("{url}")    Observable<String> uploadFile(            @Path("url") String url,            @Part("description") RequestBody description,            @Part MultipartBody.Part file);    @Multipart    @POST("{url}")    Observable<String> uploadFile(            @Path("url") String url,            @PartMap Map<String, RequestBody> map);    @GET    Call<ResponseBody> downloadFile(@Url String fileUrl);       }

Retrofit的写法和官方的没什么区别,唯一的区别就是url没有写死。定义了几个常用的get,post(key-value以及json),上传文件,下载文件等。

2.RetrofitManager.java:

    mRetrofit = new Retrofit.Builder()            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())            //.addConverterFactory(GsonConverterFactory.create())            .addConverterFactory(ScalarsConverterFactory.create())            .baseUrl(Constant.Base_Url)            .client(getOkhttpClient())            .build();    apiServer = mRetrofit.create(ApiServer.class);}private OkHttpClient getOkhttpClient() {    HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {        @Override        public void log(String message) {            NetLog.d("", message);        }    });    httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);    mOkhttp = new OkHttpClient.Builder()            .addInterceptor(httpLoggingInterceptor)            .addInterceptor(new PublicParamsInterceptor())            .connectTimeout(CONNEC_TIMEOUT, TimeUnit.SECONDS)            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)            .writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS)            .retryOnConnectionFailure(false)            .connectionPool(new ConnectionPool())            .build();    return mOkhttp;}public static RetrofitManager getInstance() {    if (mInstance == null) {        synchronized (RetrofitManager.class) {            if (mInstance == null) {                mInstance = new RetrofitManager();            }        }    }    return mInstance;}    public ApiServer getApiServer() {       return apiServer;    }

单利设计模式,因为整个项目中共用同一个网络请求即可。这些天看的14年的项目,想哭的心都有那~~~

        mRetrofit = new Retrofit.Builder()        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())        //.addConverterFactory(GsonConverterFactory.create())        .addConverterFactory(ScalarsConverterFactory.create())        .baseUrl(Constant.Base_Url)        .client(getOkhttpClient())        .build();
    看到添加了两个converter了吗,其实是这样的,本来想直接封装成BaseBean的,但是发现后台返回的数据根本就没统一,一下data,一下orders的,唯一统一的就一个resultCode字段,“SUCCESS” 代表成功,否则失败。最可气,最可气的是接口文档都没有,接下来这几天又要自己去整理下接口文档了,香菇。    这也是为什么会有StringObserver.java和BaseObserver.java两个类的出现了,可能也有更好的解决办法,这里只能选择String让调用者自己去解析了。
        mOkhttp = new OkHttpClient.Builder()        .addInterceptor(httpLoggingInterceptor)        .addInterceptor(new PublicParamsInterceptor())        .connectTimeout(CONNEC_TIMEOUT, TimeUnit.SECONDS)        .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)        .writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS)        .retryOnConnectionFailure(false)        .connectionPool(new ConnectionPool())        .build();
addInterceptor(httpLoggingInterceptor) 添加日志打印的拦截器addInterceptor(new PublicParamsInterceptor())添加公共参数的拦截器看下get,post(key—vaule,json),上传,下载/** * get请求 接口不统一  只能一个一个去解析了 * * @param url * @param params * @param observer */public void get(String url, Map<String, String> params, Observer observer) {    getApiServer().get(url, params).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);}/** * post key-value 请求 * * @param url * @param params * @param observer */public void post(String url, Map<String, String> params, Observer observer) {    getApiServer().post(url, params).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);}/** * post json请求 * * @param url * @param json * @param observer */public void json(String url, String json, Observer observer) {    RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), json);    getApiServer().post(url, body).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);}/** * 上传单个文件 * * @param url * @param file * @param progress */public void uploadFile(String url, File file, @NonNull final ProgressListener progress, Observer observer) {    OkHttpClient.Builder newBuilder = mOkhttp.newBuilder();    List<Interceptor> networkInterceptors = newBuilder.networkInterceptors();    Interceptor it = new Interceptor() {        @Override        public Response intercept(Chain arg0) throws IOException {            Request request = arg0.request();            Request build = request.newBuilder().method(request.method(), new ProgressRequestBody(request.body(), progress)).build();            return arg0.proceed(build);        }    };    networkInterceptors.add(it);    ApiServer apiServer = mRetrofit.newBuilder().client(newBuilder.build()).build().create(ApiServer.class);    RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), file);    MultipartBody.Part part = MultipartBody.Part.createFormData("image", file.getName(), body);    RequestBody des = RequestBody.create(MediaType.parse("multipart/form-data"), "des");    apiServer.uploadFile(url, des, part).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);}    /** * 下载文件 * * @param url * @param listener */public void downLoadFile(String url, @NonNull final ProgressListener listener, @NonNull final retrofit2.Callback<ResponseBody> call) {    OkHttpClient.Builder newBuilder = mOkhttp.newBuilder();    List<Interceptor> networkInterceptors = newBuilder.networkInterceptors();    Interceptor it = new Interceptor() {        @Override        public Response intercept(Chain arg0) throws IOException {            Response proceed = arg0.proceed(arg0.request());            ProgressResponseBody body = new ProgressResponseBody(proceed.body(), listener);            return proceed.newBuilder().body(body).build();        }    };    networkInterceptors.add(it);    Retrofit build = mRetrofit.newBuilder().client(newBuilder.build()).build();    ApiServer apiServer = build.create(ApiServer.class);    apiServer.downloadFile(url).enqueue(call);}

使用者直接调用即可,可能封装的不是很好,自己也是第一次使用这些框架的,有问题麻烦提出。

3.StringObserver.java

    @Override    public void onSubscribe(Disposable d) {    }    @Override    public void onNext(String s) {        try {            onSuccess(s);        }catch (Exception e){            e.printStackTrace();            ToastUtils.showMsg("发生错误,请重试!");            onComplete();        }    }    @Override    public void onError(Throwable e) {        e.printStackTrace();        onFaild(e);        onComplete();    }    protected abstract void onSuccess(String json) throws Exception;    protected abstract void onFaild(Throwable e);}

4.BaseObserver.java

    @Override    public void onSubscribe(Disposable d) {    }    @Override    public void onNext(BaseBean baseBean) {        try{            if(baseBean != null && baseBean.isSuccess()){                onSuccess(baseBean);            }else{                baseBean.showErrorMsg();            }        }catch (Exception e){            e.printStackTrace();            ToastUtils.showMsg("发生错误,请重试!");            onComplete();        }    }    @Override    public void onError(Throwable e) {        e.printStackTrace();        onFail();        onComplete();    }    @Override    public void onComplete() {    }    public abstract void onSuccess(BaseBean baseBean);    public abstract void onFail();}

回调的简单封装,如果接口文档规范的话,使用起来会更加方便。

二、MVP:

看过谷歌官方demo的话,会发现有一个contract把view和presenter关联起来,所以这里也遵循了谷歌的做法,每个界面对应了3个类,分别是presenter,constract,task。

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这应该是最基本的一个mvp Demo了,面对这么多的接口,刚开始我也无从去下手,但我们应该学会去接收新鲜事物,不断去学习,去进步。

这里强烈推荐:传统MVP用在项目中是真的方便还是累赘?
地址 http://www.jianshu.com/p/ac51c9b88af3

好了,欢迎大家前来纠正提问。

Github:https://github.com/andmizi/Rxjava-Retrofit-Okhttp-Mvp

0 0