首页 > 系统 > Android > 正文

android Retrofit2+okHttp3使用总结

2019-12-12 03:12:29
字体:
来源:转载
供稿:网友

使用前准备

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的时候这段代码就会崩溃。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表