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
- rxjava+retrofit+okhttp+mvp 简单实践
- 简单MVP-Retrofit-Rxjava-OKhttp
- RxJava+Retrofit+OkHttp+mvp
- mvp+rxjava+retrofit+okhttp
- MVP+Retrofit+Okhttp+RxJava
- Retrofit+Rxjava+Okhttp+MVP
- Retrofit实践(MVP+RxJava)
- Rxjava+Retrofit+okhttp+mvp实现
- Retrofit+RxJava+Okhttp+RecycleView+MVP简单的展示数据
- mvp demo:mvp+rxjava+retrofit(okhttp)+greendao
- RxJava+Retrofit+okhttp实践结合
- RxJava+okhttp+Retrofit+Mvp 的封装
- 网络请求框架 Rxjava+ReTrofit+okHttp+MVP
- MVP+Retrofit+RxJava+Okhttp拦截器
- MVP+Retrofit+RxJava+Okhttp拦截器
- 终极封装 Rxjava+Retrofit+okhttp+mvp实现
- MVP+Rxjava+Okhttp+Retrofit+XRecyclerview请求数据
- Okhttp+Retrofit+Rxjava+MVP联合使用
- 简约而不简单的六个ES6新特性
- VMWARE中的Linux安装jdk和tomcat
- imp导入dmp文件报:IMP-00038: 无法转换为环境字符集句柄IMP-00000: 未成功终止导入
- Java对象克隆方法(浅克隆、深克隆)
- python中出现SyntaxError: Non-UTF-8 code 解决方法
- rxjava+retrofit+okhttp+mvp 简单实践
- 跨域ifrme高宽自适应
- 查看数据库磁盘分区可用空间及错误日志的输出
- webRTC信令机制
- 蓝桥杯 ADV-212 算法提高 3-1课后习题2
- node-2
- linux awk
- Spark优化-数据倾斜解决方案 聚合源数据以及过滤导致倾斜的key
- hadoop相关记录namenode以及datanode