当前位置: 移动技术网 > 移动技术>移动开发>Android > android Retrofit2+okHttp3使用总结

android Retrofit2+okHttp3使用总结

2019年07月24日  | 移动技术网移动技术  | 我要评论

使用前准备

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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网