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):
publicclassServiceGenerator{ publicstaticfinalStringAPI_BASE_URL=""; publicstaticintREAD_TIMEOUT=60; publicstaticintWRIT_TIMEOUT=60; publicstaticintCONNECT_TIMEOUT=60; privatestaticOkHttpClient.BuilderhttpClient=newOkHttpClient.Builder() .readTimeout(READ_TIMEOUT,TimeUnit.SECONDS)//设置读取超时时间 .writeTimeout(WRIT_TIMEOUT,TimeUnit.SECONDS)//设置写的超时时间 .connectTimeout(CONNECT_TIMEOUT,TimeUnit.SECONDS); privatestaticRetrofit.Builderbuilder= newRetrofit.Builder() .baseUrl(API_BASE_URL).addConverterFactory(GsonConverterFactory.create()); publicstaticScreateService(ClassserviceClass){ returncreateService(serviceClass,null); } publicstaticScreateService(ClassserviceClass,finalStringauthToken){ if(authToken!=null){ httpClient.addInterceptor(newInterceptor(){ @Override publicResponseintercept(Interceptor.Chainchain)throwsIOException{ Requestoriginal=chain.request(); //Requestcustomization:addrequestheaders Request.BuilderrequestBuilder=original.newBuilder() .method(original.method(),original.body()); Requestrequest=requestBuilder.build(); returnchain.proceed(request); } }); } OkHttpClientclient=httpClient //日志拦截器 .addInterceptor(newHttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); Retrofitretrofit=builder.client(client).build(); returnretrofit.create(serviceClass); } }
使用说明:
API_BASE_URL用来配置api主地址
READ_TIMEOUT用来配置读取超时时间
WRIT_TIMEOUT用来配置写超时时间
CONNECT_TIMEOUT用来配置连接超时时间
addConverterFactory()用来设置解析器,此处我们设置的是gson的解析
addInterceptor()用来设置日志拦截器
服务创建类封装(HTTPS):
publicclassHttpsServiceGenerator{ publicstaticfinalStringAPI_BASE_URL=""; publicstaticintREAD_TIMEOUT=250; publicstaticintWRIT_TIMEOUT=250; publicstaticintCONNECT_TIMEOUT=250; privatestaticOkHttpClient.BuilderhttpClient=newOkHttpClient.Builder(); privatestaticRetrofit.Builderbuilder= newRetrofit.Builder() .baseUrl(API_BASE_URL).addConverterFactory(GsonConverterFactory.create()); publicstaticScreateService(ClassserviceClass){ returncreateService(serviceClass,null); } publicstaticScreateService(ClassserviceClass,finalStringauthToken){ if(authToken!=null){ httpClient.addInterceptor(newInterceptor(){ @Override publicResponseintercept(Interceptor.Chainchain)throwsIOException{ Requestoriginal=chain.request(); //Requestcustomization:addrequestheaders Request.BuilderrequestBuilder=original.newBuilder() .method(original.method(),original.body()); Requestrequest=requestBuilder.build(); returnchain.proceed(request); } }); } Retrofitretrofit=builder.client(getUnsafeOkHttpClient()).build(); returnretrofit.create(serviceClass); } privatestaticOkHttpClientgetUnsafeOkHttpClient(){ try{ //Createatrustmanagerthatdoesnotvalidatecertificatechains finalTrustManager[]trustAllCerts=newTrustManager[]{ newX509TrustManager(){ @Override publicvoidcheckClientTrusted(java.security.cert.X509Certificate[]chain,StringauthType)throwsCertificateException{ } @Override publicvoidcheckServerTrusted(java.security.cert.X509Certificate[]chain,StringauthType)throwsCertificateException{ } @Override publicjava.security.cert.X509Certificate[]getAcceptedIssuers(){ X509Certificate[]x509Certificates=newX509Certificate[0]; returnx509Certificates; } } }; //Installtheall-trustingtrustmanager finalSSLContextsslContext=SSLContext.getInstance("SSL"); sslContext.init(null,trustAllCerts,newjava.security.SecureRandom()); //Createansslsocketfactorywithourall-trustingmanager finalSSLSocketFactorysslSocketFactory=sslContext.getSocketFactory(); OkHttpClientokHttpClient= newOkHttpClient.Builder() .readTimeout(READ_TIMEOUT,TimeUnit.SECONDS)//设置读取超时时间 .writeTimeout(WRIT_TIMEOUT,TimeUnit.SECONDS)//设置写的超时时间 .connectTimeout(CONNECT_TIMEOUT,TimeUnit.SECONDS) .addInterceptor(newHttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .sslSocketFactory(sslSocketFactory) .hostnameVerifier(newHostnameVerifier(){ @Override publicbooleanverify(Stringhostname,SSLSessionsession){ returntrue; } }).build(); returnokHttpClient; }catch(Exceptione){ thrownewRuntimeException(e); } } }
使用说明:
可以看出https和http的服务类主要区别在于retrofit对象的构造方法不同。
主要就是sslSocketFactory()方法。是用来添加sslsocketFactory的,也就是客户端发送的请求都等于手持了这样的证书,这样就可以和服务器交互了。
SslsocketFactory对象的获取方法如下:
finalSSLContextsslContext=SSLContext.getInstance("SSL"); sslContext.init(null,trustAllCerts,newjava.security.SecureRandom()); finalSSLSocketFactorysslSocketFactory=sslContext.getSocketFactory();
请求体和响应体封装:
{ "page":2, "pageSize":10 }
Json体类似如上所示的可以封装为如下的请求体/响应体,此处可以借用GsonFormat插件,输入json体就可以快速生产请求体/响应体bean类。
publicclassGetTradeDetailRequest{ /** *page:2 *pageSize:10 */ privateintpage; privateintpageSize; publicintgetPage(){ returnpage; } publicvoidsetPage(intpage){ this.page=page; } publicintgetPageSize(){ returnpageSize; } publicvoidsetPageSize(intpageSize){ this.pageSize=pageSize; } }
服务接口封装:
publicinterfaceBalanceService{ @GET("balance") CallgetBalance(@Header("AccessToken")StringaccessToken); @POST("balance/detail") Call getDetail(@Header("AccessToken")StringaccessToken,@BodyGetTradeDetailRequesttradeDetailRequest); }
使用说明:
此接口用来声明请求类型,call声明的类型是返回体的bean类,@header是请求的头,@body是返回体的类型。
请求model封装:
publicclassBalanceModel{ privatestaticBalanceModelbalanceModel; privateBalanceServicemBalanceService; /** *Singleton */ publicstaticBalanceModelgetInstance(Contextcontext){ if(balanceModel==null){ balanceModel=newBalanceModel(context); } returnbalanceModel; } publicBalanceModel(Contextcontext){ mBalanceService=HttpsServiceGenerator.createService(BalanceService.class); } publicCallgetBalanceResponseCall(StringaccessToken){ Call balanceResponseCall=mBalanceService.getBalance(accessToken); returnbalanceResponseCall; } }
使用说明:
此接口用来声明请求model的,主要用到的是上面的服务接口。此类主要用来获取网络请求体的。
响应事件回调类封装:
publicabstractclassCallbackimplementsretrofit2.Callback { @Override publicvoidonResponse(Call call,Response response){ if(response.raw().code()==200){ Log.i("internetresponse","200"); onSuccess(response); }elseif(response.raw().code()==404){ Log.i("internetresponse","404"); onNotFound(); } } @Override publicvoidonFailure(Call call,Throwablet){ } publicabstractvoidonSuccess(Response response); publicvoidonNotFound(){ return; } }
使用说明:
通常在发送网络请求的时候只有两种结果,一是请求发送失败,二是服务器接收到了请求并且响应了。
onFailure()主要用来处理请求发送失败的情况,onResponse()用来处理服务器的响应内容。
response.raw().code()的值就是我们在网站开发中遇到的标识代码,200代表成功返回消息体,404代表api路径没找到(api路径配置出错是会导致这样的情况,当然也可能是服务器的环境出了问题,导致手机访问不到),500代表的是服务器内部错误(请求中的参数配置有误会导致这样的情况)。
代码中使用:
privatevoidhttpLoginRequest(Stringphone,Stringpassword){ mPushToken=mPushAgent.getRegistrationId(); GetLoginRequestloginRequest=newGetLoginRequest(); loginRequest.setPhone(phone); loginRequest.setPassword(password); loginRequest.setPushtoken(mPushToken); loginRequest.setCarrier(mCarrier); finalCallcallLogin=loginModel.getLoginResponseCall(loginRequest); callLogin.enqueue(newCallback (){ @Override publicvoidonFailure(Call calllist,Throwablet){ ToastUtils.showToast(LoginActivity.this,"网络服务异常"); materialDialog.dismiss(); callLogin.cancel(); } @Override publicvoidonSuccess(Response response){ GetLoginResponseloginResponse=response.body(); userBean=loginResponse.getData(); if(loginResponse.getErrcode()==0){ ToastUtils.showToast(LoginActivity.this,"登录成功"); ActivityCollector.finishAll(); startActivity(newIntent(LoginActivity.this,MapActivity.class)); AppConfigUtils.getInstanse(LoginActivity.this).clearAll(); AppConfigUtils.getInstanse(LoginActivity.this).setUserBean(userBean); materialDialog.dismiss(); }elseif(loginResponse.getErrcode()==203){ ToastUtils.showToast(LoginActivity.this,"用户名或密码错误"); materialDialog.dismiss(); }elseif(loginResponse.getErrcode()==999){ materialDialog.dismiss(); ToastUtils.showToast(LoginActivity.this,"服务器异常,请稍后再试"); } callLogin.cancel(); } @Override publicvoidonNotFound(){ materialDialog.dismiss(); ToastUtils.showToast(LoginActivity.this,"404"); super.onNotFound(); callLogin.cancel(); } }); } privatevoidhttpBalanceRequest(StringaccessToken){ BalanceModelbalanceModel=BalanceModel.getInstance(getApplicationContext()); finalCall balanceResponseCall=balanceModel.getBalanceResponseCall(accessToken); balanceResponseCall.enqueue(newCallback (){ @Override publicvoidonResponse(Call calllist,Response response){ GetBalanceResponsebalanceResponse=response.body(); if(balanceResponse.getErrcode()==0){ mMoneyTV.setText(balanceResponse.getData().getBalance()); }elseif(balanceResponse.getErrcode()==999){ ToastUtils.showToast(BalanceActivity.this,"服务器异常,请稍后再试"); mMoneyTV.setText("0.00"); }elseif(balanceResponse.getErrcode()==403){ ToastUtils.showToast(BalanceActivity.this,"登录已失效,请重新登录"); AppConfigUtils.getInstanse(BalanceActivity.this).clearAll(); ActivityCollector.finishAll(); LoginActivity.actionStart(BalanceActivity.this,mPhone,""); } balanceResponseCall.cancel(); } @Override publicvoidonFailure(Call calllist,Throwablet){ ToastUtils.showToast(BalanceActivity.this,"网络服务异常"); balanceResponseCall.cancel(); } }); }
使用说明:
这段代码使用的是自己封装的响应事件回调类,当然也可以用第二张图retrofit默认的那套,用自己封装的有个好处就是404notfound可以处理进行操作,如果用默认的那套,在404的时候这段代码就会崩溃。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。