MVP实战心得---封装Retrofit2,android艺术开发探索电子书

本文主要是介绍MVP实战心得---封装Retrofit2,android艺术开发探索电子书,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

public void log(String message) {
HLog.i(“RxJava”, message);
}
});

OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)//Retrofit需要配置一个OkHttpClient实例.
.baseUrl(API_HOST)//需要指定一个baseUrl,一般就是服务器的域名
.addConverterFactory(FastjsonConverterFactory.create())//这个是数据解析工厂,我用的是fastjson
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//支持rxJava,在第二个jar包里面
.build();

下面是完整代码:

/**

  • 写成单例模式,因为并不需要多个Retrofit存在.
    /
    public class RetrofitUtil {
    /
    *
  • 服务器地址
    */
    private static final String API_HOST =“你的BaseUrl”;
    private RetrofitUtil() {

}
public static Retrofit getRetrofit() {
return Instanace.retrofit;
}
//静态内部类,保证单例并在调用getRetrofit方法的时候才去创建.
private static class Instanace {
private static final Retrofit retrofit = getInstanace();
private static Retrofit getInstanace() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger(){
@Override
public void log(String message) {
HLog.i(“RxJava”, message);
}
});
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
Reretrofit = new Retrofit.Builder()
.client(client)
.baseUrl(API_HOST)
.addConverterFactory(FastjsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit;
}
}
}

json解析工厂,代码太多,具体可以见demo

3.RxAndroid

如果没接触的话,可以看前面的Rxjava链接.

(1).首先看Reretrofit+RxAndroid是怎么使用的

@GET(“login地址”)
Observable<BaseResponse> login(@QueryMap HashMap<String, Object> params);

其实所谓的Reretrofit+RxAndroid就是这么回事.

没有RxAndroid的Reretrofit请求接口是这样写的:

@GET(“login地址”)
Call<BaseResponse> login(@QueryMap HashMap<String, Object> params);

把Call换成了Observable而已.

(2)写一个接口类

/**
*所有的网络请求都可以写在这个接口类里面.
*/
public interface APIService {
@GET(“login地址”)
Observable<BaseResponse> login(@QueryMap HashMap<String, Object> params);

}

(3)接口类的实现

/**

  • 请求生成类。Retrofit一次生成,并作为单例.
    */
    public class ApiServcieImpl {
    private ApiServcieImpl() {

}
public static APIService getInstance() {
return createAPIService.apiService;
}

/**

  • Retrofit生成接口对象.
    */
    private static class createAPIService {
    //Retrofit会根据传入的接口类.生成实例对象.
    private static final APIService apiService = RetrofitUtil.getRetrofit().create(APIService.class);
    }
    }

然后就可以通过ApiServcieImpl.getInstance()去调用APIService里面写的接口了. 如:

ApiServcieImpl.getInstance().login(new HashMap<String, Object>()) //传入参数
.subscribe(new Action1<BaseResponse>() {//简单的回调
@Override
public void call(BaseResponse loginDataBaseResponse) {
//拿到数据,做处理
}
});

4.封装

有没有发现,设置泛型的是,包了一层BaseResponse 这么做是为了请求完成后对返回的数据进行统一处理.

先看BaseResponse:

public class BaseResponse {
private boolean success;//请求是否成功
private int resultCode;//状态吗
private String msg;//返回的提示消息
private T data;//主要内容,因为不知道返回的会是什么类型,所以用泛型来表示
//get set方法就不贴了.
}

怎么处理.

/**

  • @author jlanglang 2016/11/15 16:14
    */
    public class ModelFilteredFactory {
    private final static Observable.Transformer transformer = new SimpleTransformer();

/**

  • 将Observable<BaseResponse>转化Observable,并处理BaseResponse
  • @return 返回过滤后的Observable.
    */
    @SuppressWarnings(“unchecked”)
    public static Observable compose(Observable<BaseResponse> observable) {
    return observable.compose(transformer);
    }

/**

  • 这里就不细讲了,具体可以去看rxjava的使用.这个类的意义就是转换Observable.
    */
    private static class SimpleTransformer implements Observable.Transformer<BaseResponse, T> {
    //这里对Observable,进行一般的通用设置.不用每次用Observable都去设置线程以及重连设置
    @Override
    public Observable call(Observable<BaseResponse> observable) {
    return observable.subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .unsubscribeOn(Schedulers.io())
    .timeout(5, TimeUnit.SECONDS)//重连间隔时间
    .retry(5)//重连次数
    .flatMap(new Func1<BaseResponse, Observable>() {
    @Override
    public Observable call(BaseResponse tBaseResponse) {
    return flatResponse(tBaseResponse);
    }
    });
    }

/**

  • 处理请求结果,BaseResponse
  • @param response 请求结果
  • @return 过滤处理, 返回只有data数据的Observable
    */
    private Observable flatResponse(final BaseResponse response) {
    return Observable.create(new Observable.OnSubscribe() {
    @Override
    public void call(Subscriber<? super T> subscriber) {
    if (response.isSuccess()) {//请求成功
    if (!subscriber.isUnsubscribed()) {
    subscriber.onNext(response.getData());
    }
    } else {//请求失败
    int resultCode = response.getResultCode();
    if (!subscriber.isUnsubscribed()) {
    //这里抛出自定义的一个异常.可以处理服务器返回的错误.
    subscriber.onError(new APIException(response.getResultCode(), response.getMsg()));
    }
    return;
    }
    if (!subscriber.isUnsubscribed()) {//请求完成
    subscriber.onCompleted();
    }
    }
    });
    }
    }
    }

仅仅只有上面那些了么?接着看.

/**

  • @author jlanglang 2016/11/14 17:32
  • Subscriber,这个是用来处理Observable的结果的.
    */
    public abstract class SimpleSubscriber extends Subscriber {

@Override
public void onCompleted() {//这个是请求完成时调用.如果走了onError()就不会走这个方法.

}

@Override
public void onError(Throwable e) {//这里通常就处理异常
if (e instanceof APIException) {
APIException exception = (APIException) e;
ToastUtil.showToast( exception.message);
} else if (e instanceof UnknownHostException) {
ToastUtil.showToast(“请打开网络”);
} else if (e instanceof SocketTimeoutException) {
ToastUtil.showToast( “请求超时”);
} else if (e instanceof ConnectException) {
ToastUtil.showToast(“连接失败”);
} else if (e instanceof HttpException) {
ToastUtil.showToast(“请求超时”);
}else {
ToastUtil.showToast(“请求失败”);
}
e.printStackTrace();
}

@Override
public void onNext(T t) {//这里的是获得了数据,方法意思很明显,下一步干啥
if (t != null) {//这里最好判断一下是否为null.
call(t);
} else {
ToastUtil.showToast(“连接失败”);
}
}
/**
*因为具体的处理这里无法得知,所以抽象.
*/
public abstract void call(T t);
}

好了,看看现在的具体使用吧:

ModelFilteredFactory.compose(ApiServcieImpl.getInstance().login(new HashMap<String, Object>()))
.subscribe(new Simple
Subscriber() {
@Override
public void call(LoginData loginData) {

}
});
看起来之前用起来差不多,但是却做了很多的处理:
1.对Observable做了通用设置.网络重连次数,线程设置,重连时间.
2.做了对服务器返回结果的统一处理.比如根据resultcode,处理登陆过期啊啥的.
3.判断了data是否为null,不会在call()里面担心loginData是否为null
4.统一处理了请求的各种异常.

5.用到MVP中.

你以为上面那些就完了吗?NO!
如果我们在Presenter中这样调用其实是很不科学的.

ModelFilteredFactory.compose(ApiServcieImpl.getInstance().login(new HashMap<String, Object>()))

这个转换我们应该放在Modle和ModleImpl中去写

public class LoginContract{
…//view接口省略
public interface Model {
/**

  • 获取登陆数据
    ==
你以为上面那些就完了吗?NO!
如果我们在Presenter中这样调用其实是很不科学的.

ModelFilteredFactory.compose(ApiServcieImpl.getInstance().login(new HashMap<String, Object>()))

这个转换我们应该放在Modle和ModleImpl中去写

public class LoginContract{
…//view接口省略
public interface Model {
/**

  • 获取登陆数据

这篇关于MVP实战心得---封装Retrofit2,android艺术开发探索电子书的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/276437

相关文章

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

Java MQTT实战应用

《JavaMQTT实战应用》本文详解MQTT协议,涵盖其发布/订阅机制、低功耗高效特性、三种服务质量等级(QoS0/1/2),以及客户端、代理、主题的核心概念,最后提供Linux部署教程、Sprin... 目录一、MQTT协议二、MQTT优点三、三种服务质量等级四、客户端、代理、主题1. 客户端(Clien

在Spring Boot中集成RabbitMQ的实战记录

《在SpringBoot中集成RabbitMQ的实战记录》本文介绍SpringBoot集成RabbitMQ的步骤,涵盖配置连接、消息发送与接收,并对比两种定义Exchange与队列的方式:手动声明(... 目录前言准备工作1. 安装 RabbitMQ2. 消息发送者(Producer)配置1. 创建 Spr

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

深度解析Spring Boot拦截器Interceptor与过滤器Filter的区别与实战指南

《深度解析SpringBoot拦截器Interceptor与过滤器Filter的区别与实战指南》本文深度解析SpringBoot中拦截器与过滤器的区别,涵盖执行顺序、依赖关系、异常处理等核心差异,并... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Java Web实现类似Excel表格锁定功能实战教程

《JavaWeb实现类似Excel表格锁定功能实战教程》本文将详细介绍通过创建特定div元素并利用CSS布局和JavaScript事件监听来实现类似Excel的锁定行和列效果的方法,感兴趣的朋友跟随... 目录1. 模拟Excel表格锁定功能2. 创建3个div元素实现表格锁定2.1 div元素布局设计2.