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#

标签:okhttp,retrofit
0
投稿

猜你喜欢

  • 一篇文章教你使用枚举来实现java单例模式

    2023-08-23 22:24:36
  • SpringBoot自动装配原理详解

    2023-07-26 08:44:46
  • Jetpack Compose修饰符专项精讲

    2021-11-28 06:33:21
  • c# socket网络编程接收发送数据示例代码

    2021-08-31 06:14:13
  • C#使用iTextSharp操作PDF

    2023-07-29 02:03:11
  • Android实现IM多人员组合的群组头像

    2023-05-24 06:39:54
  • 新手学习Java对Redis简单操作

    2023-09-10 05:05:41
  • 使用JPA进行CriteriaQuery进行查询的注意事项

    2023-07-03 23:36:05
  • Java多线程之Semaphore实现信号灯

    2023-09-19 23:04:51
  • java中javaBean与Bean的深入理解

    2021-11-27 13:19:11
  • Android实现布局全屏

    2023-11-29 06:44:13
  • C#计算两个文件的相对目录算法的实例代码

    2022-08-27 10:27:44
  • C#泛型的使用案例

    2023-10-01 23:24:00
  • SpringCloud:feign对象传参和普通传参及遇到的坑解决

    2023-02-17 11:18:58
  • C# 判断字符串第一位是否为数字

    2023-05-29 20:06:44
  • 在Maven下代理服务器设定的方式

    2023-10-15 02:17:13
  • java 出现Zipexception 异常的解决办法

    2022-11-07 11:03:03
  • IntelliJ IDEA 2021.1 推出语音、视频功能,边写代码边聊天(功能超级强大)

    2023-09-13 23:30:37
  • spring profile 多环境配置管理详解

    2023-01-23 17:53:58
  • C#设置文件权限的方法

    2022-08-31 22:35:42
  • asp之家 软件编程 m.aspxhome.com