android Retrofit2+okHttp3使用总结
使用前准备
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的时候这段代码就会崩溃。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Android编程实现全局获取Context及使用Intent传递对象的方法详解
-
Android studio使用git代码追溯到上个文件的教程?
-
Android 使用 DowanloadManager 实现下载并获取下载进度实例代码
-
Android学习之本地广播使用方法详解
-
Android学习之Broadcast的简单使用
-
解决Android使用Handler造成内存泄露问题
-
Android 布局中的android:onClick的使用方法总结
-
Android 使用volley过程中遇到的问题解决办法
-
Android中的脑残设计总结
-
android startActivityForResult的使用方法介绍