android Retrofit2+okHttp3使用总结
作者:林水吉 发布时间:2023-07-31 21:02:10
使用前准备
Build.gradle文件配置
dependencies配置
compile 'com.squareup.retrofit2:retrofit:2.0.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
网络框架搭建
服务创建类封装(HTTP):
public class ServiceGenerator {
public static final String API_BASE_URL = "";
public static int READ_TIMEOUT = 60;
public static int WRIT_TIMEOUT = 60;
public static int CONNECT_TIMEOUT = 60;
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.readTimeout(READ_TIMEOUT,TimeUnit.SECONDS)//设置读取超时时间
.writeTimeout(WRIT_TIMEOUT,TimeUnit.SECONDS)//设置写的超时时间
.connectTimeout(CONNECT_TIMEOUT,TimeUnit.SECONDS);
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL) .addConverterFactory(GsonConverterFactory.create());
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null);
}
public static <S> S createService(Class<S> serviceClass, final String authToken) {
if (authToken != null) {
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
}
OkHttpClient client = httpClient
// 日志 *
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
Retrofit retrofit = builder.client(client).build();
return retrofit.create(serviceClass);
}
}
使用说明:
API_BASE_URL 用来配置api主地址
READ_TIMEOUT 用来配置读取超时时间
WRIT_TIMEOUT 用来配置写超时时间
CONNECT_TIMEOUT 用来配置连接超时时间
addConverterFactory() 用来设置解析器,此处我们设置的是gson的解析
addInterceptor() 用来设置日志 *
服务创建类封装(HTTPS):
public class HttpsServiceGenerator {
public static final String API_BASE_URL = "";
public static int READ_TIMEOUT = 250;
public static int WRIT_TIMEOUT = 250;
public static int CONNECT_TIMEOUT = 250;
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL) .addConverterFactory(GsonConverterFactory.create());
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null);
}
public static <S> S createService(Class<S> serviceClass, final String authToken) {
if (authToken != null) {
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
}
Retrofit retrofit = builder.client(getUnsafeOkHttpClient()).build();
return retrofit.create(serviceClass);
}
private static OkHttpClient getUnsafeOkHttpClient() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
X509Certificate[] x509Certificates = new X509Certificate[0];
return x509Certificates;
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient okHttpClient =
new OkHttpClient.Builder()
.readTimeout(READ_TIMEOUT,TimeUnit.SECONDS)//设置读取超时时间
.writeTimeout(WRIT_TIMEOUT,TimeUnit.SECONDS)//设置写的超时时间
.connectTimeout(CONNECT_TIMEOUT,TimeUnit.SECONDS)
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.sslSocketFactory(sslSocketFactory)
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
使用说明:
可以看出https 和http的服务类主要区别在于retrofit对象的构造方法不同。
主要就是sslSocketFactory()方法。是用来添加sslsocketFactory的,也就是客户端发送的请求都等于手持了这样的证书,这样就可以和服务器交互了。
SslsocketFactory对象的获取方法如下:
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
请求体和响应体封装:
{
"page":2,
"pageSize":10
}
Json体类似如上所示的可以封装为如下的请求体/响应体,此处可以借用GsonFormat插件,输入json体就可以快速生产请求体/响应体bean类。
public class GetTradeDetailRequest {
/**
* page : 2
* pageSize : 10
*/
private int page;
private int pageSize;
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
}
服务接口封装:
public interface BalanceService {
@GET("balance")
Call<GetBalanceResponse> getBalance(@Header("AccessToken") String accessToken);
@POST("balance/detail")
Call<GetTradeDetailResponse> getDetail(@Header("AccessToken") String accessToken , @Body GetTradeDetailRequest tradeDetailRequest);
}
使用说明:
此接口用来声明请求类型,call声明的类型是返回体的bean类,@header是请求的头,@body是返回体的类型。
请求model封装:
public class BalanceModel {
private static BalanceModel balanceModel;
private BalanceService mBalanceService;
/**
* Singleton
*/
public static BalanceModel getInstance(Context context) {
if (balanceModel == null) {
balanceModel = new BalanceModel(context);
}
return balanceModel;
}
public BalanceModel(Context context) {
mBalanceService = HttpsServiceGenerator.createService(BalanceService.class);
}
public Call<GetBalanceResponse> getBalanceResponseCall(String accessToken) {
Call<GetBalanceResponse> balanceResponseCall = mBalanceService.getBalance(accessToken);
return balanceResponseCall;
}
}
使用说明:
此接口用来声明请求model的,主要用到的是上面的服务接口。 此类主要用来获取网络请求体的。
响应事件回调类封装:
public abstract class Callback<T extends Object> implements retrofit2.Callback<T> {
@Override
public void onResponse(Call<T> call, Response<T> response) {
if (response.raw().code() == 200){
Log.i("internet response","200");
onSuccess(response);
}else if (response.raw().code() == 404){
Log.i("internet response","404");
onNotFound();
}
}
@Override
public void onFailure(Call<T> call, Throwable t) {
}
public abstract void onSuccess(Response<T> response);
public void onNotFound(){
return;
}
}
使用说明:
通常在发送网络请求的时候只有两种结果,一是请求发送失败,二是服务器接收到了请求并且响应了。
onFailure()主要用来处理请求发送失败的情况,onResponse()用来处理服务器的响应内容。
response.raw().code()的值就是我们在网站开发中遇到的标识代码,200代表成功返回消息体,404代表api路径没找到(api路径配置出错是会导致这样的情况,当然也可能是服务器的环境出了问题,导致手机访问不到),500代表的是服务器内部错误(请求中的参数配置有误会导致这样的情况)。
代码中使用:
private void httpLoginRequest(String phone, String password) {
mPushToken = mPushAgent.getRegistrationId();
GetLoginRequest loginRequest = new GetLoginRequest();
loginRequest.setPhone(phone);
loginRequest.setPassword(password);
loginRequest.setPushtoken(mPushToken);
loginRequest.setCarrier(mCarrier);
final Call<GetLoginResponse> callLogin = loginModel.getLoginResponseCall(loginRequest);
callLogin.enqueue(new Callback<GetLoginResponse>() {
@Override
public void onFailure(Call<GetLoginResponse> calllist, Throwable t) {
ToastUtils.showToast(LoginActivity.this,"网络服务异常");
materialDialog.dismiss();
callLogin.cancel();
}
@Override
public void onSuccess(Response<GetLoginResponse> response) {
GetLoginResponse loginResponse = response.body();
userBean = loginResponse.getData();
if (loginResponse.getErrcode() == 0) {
ToastUtils.showToast(LoginActivity.this,"登录成功");
ActivityCollector.finishAll();
startActivity(new Intent(LoginActivity.this, MapActivity.class));
AppConfigUtils.getInstanse(LoginActivity.this).clearAll();
AppConfigUtils.getInstanse(LoginActivity.this).setUserBean(userBean);
materialDialog.dismiss();
} else if (loginResponse.getErrcode() == 203) {
ToastUtils.showToast(LoginActivity.this,"用户名或密码错误");
materialDialog.dismiss();
}else if (loginResponse.getErrcode() == 999){
materialDialog.dismiss();
ToastUtils.showToast(LoginActivity.this,"服务器异常,请稍后再试");
}
callLogin.cancel();
}
@Override
public void onNotFound() {
materialDialog.dismiss();
ToastUtils.showToast(LoginActivity.this,"404");
super.onNotFound();
callLogin.cancel();
}
});
}
private void httpBalanceRequest(String accessToken) {
BalanceModel balanceModel = BalanceModel.getInstance(getApplicationContext());
final Call<GetBalanceResponse> balanceResponseCall = balanceModel.getBalanceResponseCall(accessToken);
balanceResponseCall.enqueue(new Callback<GetBalanceResponse>() {
@Override
public void onResponse(Call<GetBalanceResponse> calllist, Response<GetBalanceResponse> response) {
GetBalanceResponse balanceResponse = response.body();
if (balanceResponse.getErrcode() == 0) {
mMoneyTV.setText(balanceResponse.getData().getBalance());
} else if (balanceResponse.getErrcode() == 999) {
ToastUtils.showToast(BalanceActivity.this,"服务器异常,请稍后再试");
mMoneyTV.setText("0.00");
} else if (balanceResponse.getErrcode() == 403) {
ToastUtils.showToast(BalanceActivity.this,"登录已失效,请重新登录");
AppConfigUtils.getInstanse(BalanceActivity.this).clearAll();
ActivityCollector.finishAll();
LoginActivity.actionStart(BalanceActivity.this,mPhone,"");
}
balanceResponseCall.cancel();
}
@Override
public void onFailure(Call<GetBalanceResponse> calllist, Throwable t) {
ToastUtils.showToast(BalanceActivity.this,"网络服务异常");
balanceResponseCall.cancel();
}
});
}
使用说明:
这段代码使用的是自己封装的响应事件回调类,当然也可以用第二张图retrofit默认的那套,用自己封装的有个好处就是404not found 可以处理进行操作,如果用默认的那套,在404的时候这段代码就会崩溃。
来源:http://www.jianshu.com/p/a3fed8138457#


猜你喜欢
- Scala小程序详解1. 交互式模式在命令行窗口中,输入Scala命令:xiaosi@Qunar:~$ scalaWelcome to S
- 本文介绍了C# 用什么方法将BitConverter.ToString产生字符串再转换回去,分享给大家,具体如下:byte[]
- spring-data-redis简介spring-data-redis是spring-data模块的一部分,专门用来支持在spring管理
- 说明本案例使用Unity2019.3.8f1与AndropidStudio3.6.3源码git地址:https://github.com/g
- JAVA的 * 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤
- IO流代码:void LoadByIO() { float time = Time.t
- 1.App的启动流程,从startActivity到Activity被创建。这个流程主要是ActivityThread和ActivityMa
- 定时任务技术趋势简介:定时任务是每个业务常见的需求,比如每分钟扫描超时支付的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报
- 本文实例为大家分享了Android App自动更新通知栏下载的具体代码,供大家参考,具体内容如下版本更新说明这里有调用UpdateServi
- 若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法。虚方法与非虚方法的最大不同是,虚方法的实现可以由派生类所取代,这种取代
- 实现的功能比较简单,就是随机产生了四个字符然后输出。效果图如下,下面我会详细说一下实现这个功能用到了那些知识点,并且会把 这些知识点详细的介
- 本文实例讲述了C#画笔使用复合数组绘制单个矩形的方法。分享给大家供大家参考。具体实现方法如下:using System;using Syst
- 1. Java对象结构Java对象结构包括三部分:对象头、对象体和填充字节,如图所示:对象头又包括三个字段:第一个字段叫作Mark Word
- 因为某个项目需要,为团队其他兄弟姐妹开发了一个 XML 分析处理器,并将其设计为一个类库,提供相应的 API 接口。为了方便大家的使用,需要
- 本文实例为大家分享了Java实现多线程在线聊天的具体代码,供大家参考,具体内容如下上一篇博客通过UDP实现了聊天,但只能单方面发送消息,这次
- C#用户定义类型转换•用于自定义类和结构能够进行隐式转换和显示转换.例如:将一个自定义类类型转换成整型,浮点型等,反之亦然.C#提供隐式转换
- Java程序有的时候在主线程中会创建多个线程去执行任务,然后在主线程执行完毕之前,把所有线程的任务进行汇总,以前可以用线程的join方法,但
- 侧滑菜单在很多应用中都会见到,最近QQ5.0侧滑还玩了点花样~~对于侧滑菜单,一般大家都会自定义ViewGroup,然后隐藏菜单栏,当手指滑
- 前言相信这个方法Canvas.drawText大家一定不陌生,TextView就是使用它将文字绘制出来。可是这个方法并没有文字换行的功能,也
- JavaFx中其实也可以直接使用字体图标iconfont的,只需要加载ttf字体文件,之后设置unicode即可,具体可以看我给出的代码既然