Android使用RxJava+Retrofit2+Okhttp+MVP练习的APP
Android使用RxJava+Retrofit2+Okhttp+MVP练习的APP
项目截图




这是我的目录结构

五步使用RxJava+Retrofit2+Okhttp+RxCache
第一步:导包
compile 'io.reactivex:rxjava:1.1.8' compile 'io.reactivex:rxandroid:1.2.1' compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4' compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4' compile 'com.github.VictorAlbertos.RxCache:core:1.4.6'
第二步:新建API接口
public interface GanHuoService { @GET("data/{type}/{number}/{page}") Observable<DataResults> getDataResults( @Path("type") String type, @Path("number") int number, @Path("page") int page ); }
/** * 缓存API接口 * * @LifeCache设置缓存过期时间. 如果没有设置@LifeCache , 数据将被永久缓存理除非你使用了 EvictProvider, EvictDynamicKey or EvictDynamicKeyGroup . * EvictProvider可以明确地清理清理所有缓存数据. * EvictDynamicKey可以明确地清理指定的数据 DynamicKey. * EvictDynamicKeyGroup 允许明确地清理一组特定的数据. DynamicKeyGroup. * DynamicKey驱逐与一个特定的键使用EvictDynamicKey相关的数据。比如分页,排序或筛选要求 * DynamicKeyGroup。驱逐一组与key关联的数据,使用EvictDynamicKeyGroup。比如分页,排序或筛选要求 */ public interface CacheProviders { //缓存时间 1天 @LifeCache(duration = 7, timeUnit = TimeUnit.DAYS) Observable<Reply<List<DataResults>>> getHomeTypes(Observable observable, DynamicKey userName, EvictDynamicKey evictDynamicKey); }
public abstract class RetrofitUtils { private static Retrofit mRetrofit; private static OkHttpClient mOkHttpClient; /** * 获取Retrofit对象 * * @return */ protected static Retrofit getRetrofit() { if (null == mRetrofit) { if (null == mOkHttpClient) { mOkHttpClient = OkHttp3Utils.getOkHttpClient(); } //Retrofit2后使用build设计模式 mRetrofit = new Retrofit.Builder() //设置服务器路径 .baseUrl(Constant.API_SERVER + "/") //添加转化库,默认是Gson .addConverterFactory(GsonConverterFactory.create()) //添加回调库,采用RxJava .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //设置使用okhttp网络请求 .client(mOkHttpClient) .build(); } return mRetrofit; } }
/* * 所有的请求数据的方法集中地 * 根据MovieService的定义编写合适的方法 * 其中observable是获取API数据 * observableCahce获取缓存数据 * new EvictDynamicKey(false) false使用缓存 true 加载数据不使用缓存 */ public class HttpData extends RetrofitUtils { private static File cacheDirectory = FileUtil.getcacheDirectory(); private static final CacheProviders providers = new RxCache.Builder() .persistence(cacheDirectory) .using(CacheProviders.class); protected static final GanHuoService service = getRetrofit().create(GanHuoService.class); private static class SingletonHolder { private static final HttpData INSTANCE = new HttpData(); } public static HttpData getInstance() { return SingletonHolder.INSTANCE; } public void getHomeInfo(Observer<DataResults> observer, boolean isUseCache,String type, int number, int page) { Observable observable= service.getDataResults(type,number,page); Observable observableCahce=providers.getHomeTypes(observable,new DynamicKey("首页"),new EvictDynamicKey(!isUseCache)).map(new HttpResultFuncCcche<List<DataResults>>()); setSubscribe(observableCahce,observer); } /** * 插入观察者 * * @param observable * @param observer * @param <T> */ public static <T> void setSubscribe(Observable<T> observable, Observer<T> observer) { observable.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.newThread())//子线程访问网络 .observeOn(AndroidSchedulers.mainThread())//回调到主线程 .subscribe(observer); } /** * 用来统一处理RxCacha的结果 */ private class HttpResultFuncCcche<T> implements Func1<Reply<T>, T> { @Override public T call(Reply<T> httpResult) { return httpResult.getData(); } } }
public class HomeFragmentModel { public void loadData(final OnLoadDataListListener listener,boolean isUseCache ,String type, int number, int page) { HttpData.getInstance().getHomeInfo(new Observer<DataResults>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { listener.onFailure(e); } @Override public void onNext(DataResults homeDto) { listener.onSuccess(homeDto); } }, isUseCache,type,number,page); } }
MVC (Model-View-Controller)
M是指逻辑模型,V是指视图模型,C则是控制器。一个逻辑模型可以对于多种视图模型
使用MVC的目的是将M和V的实现代码分离,方便扩展,便于以后的管理
从开发者的角度,MVC把应用程序的逻辑层与界面是完全分开的,最大的好处是:界面设计人员可以直接参与到界面开发,程序员就可以把精力放在逻辑层上。
虽然理论上可以实现,但实践起来还是感觉不能完全分开...
Android中也可以说采用了当前比较流行的MVC框架,在Android中:
1) 视图层(View):一般采用XML文件进行界面的描述,使用的时候可以非常方便的引入,但是用xml编写了,又需要在Acitvity声明并且实例化。
2) 控制层(Controller):Android的控制层的重任通常落在了众多的Acitvity的肩上,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。
3) 模型层(Model):对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。
MVP
MVP 就是基于MVC 的模式上的一个演化版本。在MVC模式中,Activity应该是属于View这一层。而实质上,它既承担了View,同时也包含一些Controller的东西在里面。随着项目的迭代更新,这对开发很不友好,耦合度也原来越高,项目越来越难维护,而MVP 就是解决这样的痛点。把Activity的View和Controller抽离出来就变成了View和Presenter。
MVP的优点:
模型与视图完全分离,我们可以修改视图而不影响模型
可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)
public class HomeFragmentModel { public void loadData(final OnLoadDataListListener listener,boolean isUseCache ,String type, int number, int page) { HttpData.getInstance().getHomeInfo(new Observer<DataResults>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { listener.onFailure(e); } @Override public void onNext(DataResults homeDto) { listener.onSuccess(homeDto); } }, isUseCache,type,number,page); } }
public interface HomeFragmentView { //显示加载页 void showProgress(); //关闭加载页 void hideProgress(); //加载新数据 void newDatas(DataResults data); //显示加载失败 void showLoadFailMsg(); }
public class HomePresenter implements OnLoadDataListListener<DataResults> { private HomeFragmentView mView; private HomeFragmentModel mModel; public HomePresenter(HomeFragmentView mView) { this.mView = mView; this.mModel=new HomeFragmentModel(); mView.showProgress(); } public void getDataResults(boolean isUseCache,String type, int number, int page) { mModel.loadData(this,isUseCache,type,number,page); } @Override public void onSuccess(DataResults data) { mView.newDatas(data); mView.hideProgress(); } @Override public void onFailure(Throwable e) { Log.e("onFailure",e.toString()); mView.showLoadFailMsg(); } }
public class DiscoveryFragment extends BaseFragment implements HomeFragmentView { private HomePresenter homePresenter; @Override protected View initView(LayoutInflater inflater, ViewGroup container) { return inflater.inflate(R.layout.fragment_list, container, false); } @Override protected void initData(Bundle savedInstanceState) { homePresenter = new HomePresenter(this); } @Override protected void loadData() { getData(isFirst); } private void getData(boolean isUseCache) { switch (mTitle) { case "首页": if (isTop) { NOW_PAGE_FI = 1; } homePresenter.getDataResults(isUseCache,"all", fi_num, NOW_PAGE_FI); break; } } @Override public void newDatas(DataResults dataResults) { if (dataResults.isError()) { Snackbar.make(recyclerview, "服务器出问题啦", Snackbar.LENGTH_SHORT).show(); } else { if (mTitle.equals("干货")) { ganhuo_list = new ArrayList<>(); ganhuo_list.addAll(dataResults.getResults()); } } } private void clearAdapterResults() { switch (mTitle) { case "首页": partAdapter.getResults().clear(); break; case "妹纸": girlyAdapter.getResults().clear(); break; } } @Override public void showLoadFailMsg() { Snackbar.make(recyclerview, "网络不顺畅嘞,更新不了数据啦", Snackbar.LENGTH_SHORT).show(); } @Override public void showProgress() { } @Override public void hideProgress() { } }
Android使用RxJava+Retrofit2+Okhttp+MVP练习的APP的更多相关文章
- 学习RxJava+Retrofit+OkHttp+MVP的网络请求使用
公司的大佬用的是这一套,那我这个菜鸟肯定要学习使用了. 我在网上找了很多文章,写的都很详细,比如 https://www.jianshu.com/u/5fd2523645da https://www. ...
- android打飞机游戏、MVP句子迷App、悬浮窗、RxJava+Retrofit、加载动画、定制计划App等源码
Android精选源码 微信打飞机 android进度设置加载效果源码 Android新手引导库EasyGuide MVP-好看又好用的句子迷客户端 XFloatView 一个简易的悬浮窗实现方案 a ...
- Android 基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器aaa
MDPlayer万能播放器 MDPlayer,基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器,可以播 ...
- Rxjava + retrofit + dagger2 + mvp搭建Android框架
最近出去面试,总会被问到我们项目现在采用的什么开发框架,不过据我的经验网络框架(volley)+图片缓存(uIl)+数据库(orm)+mvp,不过现在这套框架比较好了,现在采用什么呢?Rxjava + ...
- Retrofit + RxJava + OkHttp 让网络请求变的简单-基础篇
https://www.jianshu.com/p/5bc866b9cbb9 最近因为手头上的工作做完了,比较闲,想着做一些优化.看到以前用的那一套网络框架添加一个请求比较麻烦,并且比较难用,所以想改 ...
- okhttputils【 Android 一个改善的okHttp封装库】使用(三)
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这一篇主要讲一下将OkHttpUtils运用到mvp模式中. 数据请求地址:http://www.wanandroid.com/to ...
- RxJava+Retrofit+OkHttp,一步一步封装网络框架;
使用RxJava+Retrofit+OkHttp,首先在build.gradle添加: compile 'com.squareup.okhttp3:okhttp:3.8.1' compile 'com ...
- okhttputils【 Android 一个改善的okHttp封装库】使用(一)
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本文使用的OKHttp封装库是张鸿洋(鸿神)写的,因为在项目中一直使用这个库,所以对于一些常用的请求方式都验证过,所以特此整理下. ...
- Android 使用RxJava实现一个发布/订阅事件总线
1.简单介绍 1.1.发布/订阅事件主要用于网络请求的回调. 事件总线可以使Android各组件之间的通信变得简单,而且可以解耦. 其实RxJava实现事件总线和EventBus比较类似,他们都依据与 ...
随机推荐
- NHibernate教程(18)--对象状态
本节内容 引入 对象状态 对象状态转换 结语 引入 在程序运行过程中使用对象的方式对数据库进行操作,这必然会产生一系列的持久化类的实例对象.这些对象可能是刚刚创建并准备存储的,也可能是从数据库中查询的 ...
- EIGRP系统复习【转载】
EIGRP理论 简介 EIGRP是Cisco私有协议,它是由距离矢量和链路状态两种路由协议混合而成的一种协议.即像距离矢量协议那样,EIGRP从它的相邻路由器那里得到更新信息:也像链路状态协议那样,保 ...
- 201521123080《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 多线程: 操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己 ...
- 201521123102 《Java程序设计》第11周学习总结
1. 本周学习总结 2.书面作业 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问)## 1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥同步 ...
- Markdow使用的简单介绍
一个例子: 例子开始 1. 本章学习总结 (字体较大,用法:#你要放大的标题) 今天主要学习了三个知识点 封装 继承 多态 用法: - 封装 - 继承 - 多态 2. 书面作业 Q1. java He ...
- UVW源码漫谈(二)
前一篇发布出来之后,我看着阅读量还是挺多的,就是评论和给意见的一个都没有,或许各位看官就跟我一样,看帖子从不回复,只管看就行了.毕竟大家都有公务在身,没太多时间,可以理解.不过没关系,我是不是可以直接 ...
- python之路模块与包
一.import加载的模块分为四个通用类别: 1 使用python编写的代码(.py文件) 2 已被编译为共享库或DLL的C或C++扩展 3 包好一组模块的包 4 使用C编写并链接到 ...
- mysql水平分表和垂直分表的优缺点
表分割有两种方式: 1.水平分割:根据一列或多列数据的值把数据行放到两个独立的表中. 水平分割通常在下面的情况下使用. •表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数 ...
- 手機Web頁面信息
手機瀏覽器的寬度為980px: 使用980px寫頁面時,若是遇到字體變大情況,是因為block或者inline-block沒有設置寬高.設置即顯示正常. 980px設計,禁止手機頁面縮放: <m ...
- Java实现CORS跨域请求
问题 使用前后端分离模式开发项目时,往往会遇到这样一个问题 -- 无法跨域获取服务端数据 这是由于浏览器的同源策略导致的,目的是为了安全.在前后端分离开发模式备受青睐的今天,前端和后台项目往往会在不同 ...