首先需要引入依赖
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
implementation 'com.squareup.okio:okio:2.7.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.google.code.gson:gson:2.8.6'
首先我们创建一个okhttpmanager单例类,为了获取okhttpclient
val builder = OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .sslSocketFactory( SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getTrustManager()[0] as X509TrustManager ) .hostnameVerifier(SSLSocketClient.getHostnameVerifier()) //cookieJar 处理okhttp和webview cookie同步 //.cookieJar(WebViewCookieHandler(context)) .cache(Cache(File(context.externalCacheDir, "okHttpCache"), Globals.REQUEST_CACHE_SIZE)) //拦截器,处理访问时携带的参数 builder.addInterceptor { val httpUrl = it.request().url val httpMainUrl = context.getString(R.string.url).toHttpUrlOrNull() val request: Request = if (httpUrl.host == httpMainUrl!!.host) { it.request().newBuilder() .addHeader("authenticate", MyApp.instance.userInfo().token ?: "") .build() } else { it.request() } it.proceed(request) } //拦截器 退出拦截 builder.addInterceptor { val request = it.request() val response = it.proceed(request) //这里约定后台返回401状态码,就表示没有登录状态了 if (response.code == 401) { //这里需要进行退出系统处理 return@addInterceptor response.newBuilder().build() } return@addInterceptor response } //这样就获取到okhttpclient了 builder.build()
这里贴上上面用到的 SSLSocketClient类
public class SSLSocketClient { private static final List<String> VERIFY_HOST_NAME_ARRAY = new ArrayList<String>(){{ add("www.test.com"); }}; //获取这个SSLSocketFactory public static SSLSocketFactory getSSLSocketFactory() { try { //SSLContext sslContext = SSLContext.getInstance("SSL"); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, getTrustManager(), new SecureRandom()); return sslContext.getSocketFactory(); } catch (Exception e) { throw new RuntimeException(e); } } //获取TrustManager public static TrustManager[] getTrustManager() { return new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } } }; } //获取HostnameVerifier public static HostnameVerifier getHostnameVerifier() { return (s, sslSession) -> { if(TextUtils.isEmpty(s)){ return false; } return !Arrays.asList(VERIFY_HOST_NAME_ARRAY).contains(s); }; } }
然后我们开始写retrofitclient类
class RetrofitClient private constructor() { private lateinit var retrofit: Retrofit companion object { val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { RetrofitClient() } } init { createRetrofit() } private fun createRetrofit() { retrofit = Retrofit.Builder().baseUrl("https://www.test.com/web-api/") .client(OkHttpManager.instance.client()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() } fun <T> getService(service: Class<T>): T { return retrofit.create(service) } }
然后定义api
interface LoginApi { @PUT("login") fun login(@Query("username") username :String,@Query("pass") pass :String):Observable<ResponseWrapper<LoginRespBean>> }
@GET get请求 @POST post请求 @PUT put 请求 @DELETE delete请求
一般put请求我们一般会使用@Body传递 比如 @Body loginBean:LoginBean LoginBean(username,pass)
@Path [@GET("user/{id}") fun userInfo(@Path("id") uid:String) ]
LoginRespBean 定义的用户的唯一ID ,用户的一些基本信息和登录凭证信息
ResponseWrapper类
data class ResponseWrapper<out T>(val code: Int, val msg: String, val data: T)
接下来我们开始使用
RetrofitClient.instance.getService(LoginApi::class.java) .login("用户名", "密码") .compose(NetworkScheduler.compose()) .subscribe({ if (it.code == RespCode.OK) { //登录成功 } else { //登录失败 } }, { //出现异常了 //这里异常的代码块,我们不能省略,可以空实现,如果配置了全局异常处理,异常处理的代码块可以省略掉
//subscribe {}
}) //这里贴一下全局异常处理 这个代码放到自定义的application类中即可 RxJavaPlugins.setErrorHandler { MyLog.e("RxJava统一错误处理", "======" + it.message) }
NetworkScheduler类
object NetworkScheduler { fun <T> compose(): ObservableTransformer<T,T>{ return ObservableTransformer { it.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) } } }