欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android Retrofit2+okHttp3使用总结

程序员文章站 2022-06-14 09:33:37
使用前准备 build.gradle文件配置 dependencies配置 compile 'com.squareup.retrofit2:retrofi...

使用前准备

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

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