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比较类似,他们都依据与 ...
随机推荐
- mpls vpn剩余笔记
将IP地址映射为简单的具有固定长度的标签 用于快速数据包交换 20 3 1 8 在整个转发过程中,交换节点仅根据标记进行转发 标签交换路径(LSP) 多协议标签交换MPLS最初是为了提高转发速度而提出 ...
- ps中如何让图层在画布内水平居中
下图每个小logo图案距离它们的上参考线的距离均为10px,而我们如何让图层在画布内水平居中??? 如上图中三个图层的图案是用来给Html/Css中的background属性使用的,虽然可以通过鼠标拖 ...
- 201521123010 《Java程序设计》第14周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...
- 32位汇编第六讲,OllyDbg逆向植物大战僵尸,快速定位阳光基址
32位汇编第六讲,OllyDbg逆向植物大战僵尸,快速定位阳光基址 一丶基址,随机基址的理解 首先,全局变量的地址,我们都知道是固定的,是在PE文件中有保存的 但是高版本有了随机基址,那么要怎么解决这 ...
- birt 报表设计总结
1, 通过sql查询出来的数据,当某个字段没有值时,我们期望显示别的东东 在表格单元格或者网格中选中这个值, 在属性编辑器-->映射--> 在映射表中添加映射条件 映射中当使用 等于 时, ...
- Sublime Text 3 全程详细图文原创教程
Sublime Text 3 全程详细图文原创教程(持续更新中...) 一. 前言 使用Sublime Text 也有几个年头了,版本也从2升级到3了,但犹如寒天饮冰水,冷暖尽自知.最初也是不知道从何 ...
- day09<面向对象+>
面向对象(多态的概述及其代码体现) 面向对象(多态中的成员访问特点之成员变量) 面向对象(多态中的成员访问特点之成员方法) 面向对象(多态中的成员访问特点之静态成员方法) 面向对象(超人的故事) 面向 ...
- js 倒计时(服务器时间同步)
首先说一下,为什么要服务器时间同步, 因为服务器时间和本地电脑时间存在一定的时间差.有些对时效性要求非常高的应用,例如时时彩开奖,是不能容忍这种时间差存在的. 方案1:每次倒计时去服务端请求时间 // ...
- 集成Mybatis
本文根据个人喜好记录"腾讯课堂"的<Java项目之Maven+SpringMVC+Spring+Mybatis+MySql消费查询系统>视频教程关键步骤信息,视频地址: ...
- 自定义工作流活动报错:您无法登陆系统。原因可能是您的用户记录或您所属的业务部门在Microsoft Dynamics 365中已被禁用。
本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复265或者20170926可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...