[toc]
依赖
ext.kotlin_version = "1.5.0"
ext.retrofit_version = "2.9.0"
ext.ok_http_version = "3.4.1"
ext.rx_kotlin_version = '3.0.1'
ext.rx_android_version ='3.0.0'
implementation "com.squareup.okhttp3:okhttp:$ok_http_version"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.okhttp3:logging-interceptor:$ok_http_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation "com.squareup.retrofit2:adapter-rxjava3:$retrofit_version"
implementation "io.reactivex.rxjava3:rxkotlin:$rx_kotlin_version"
implementation "io.reactivex.rxjava3:rxandroid:${rx_android_version}"
封装步骤
1.配置Retrofit,okHttpClient
/**
* create by Admin in 2021/6/8
*
* @Description : retrofit封装
**/
class RetrofitFactory {
private lateinit var retrofit:Retrofit
companion object{
//单例
val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
RetrofitFactory()
}
}
/**
* 组装retrofit对象
*/
init {
retrofit = Retrofit.Builder()
.baseUrl(NetContants.BASE_URL)
.client(getClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.build()
}
/**
* 组装client
*/
private fun getClient(): OkHttpClient {
return OkHttpClient.Builder()
.writeTimeout(10,TimeUnit.SECONDS)
.readTimeout(10,TimeUnit.SECONDS)
.connectTimeout(10,TimeUnit.SECONDS)
.addInterceptor(getLogInterceptor())
.build()
}
/**
* log 拦截器
*/
private fun getLogInterceptor(): Interceptor {
val logInterceptor = HttpLoggingInterceptor()
logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
return logInterceptor
}
/**
* service
*/
fun <T> create(service:Class<T>):T{
return retrofit.create(service)
}
}
2.创建请求接口apiService
/**
* create by Admin in 2021/6/8
*
* @Description : retrofit抽象接口
**/
interface UserApiService {
//登录接口
@FormUrlEncoded
@POST("user/login")
fun login(@Field("userName") userName: String,
@Field("password") password: String): Observable<BaseRep<LoginBean>>
}
2.1返回数据封装
/**
* create by Admin in 2021/6/8
*
* @Description : 接口返回格式
**/
data class BaseRep<T>(val data:T,val errorCode:Int,val errorMsg:String)
3.请求接口
/**
* create by Admin in 2021/6/8
*
* @Description : 用户模块接口请求
**/
class UserServiceImpl : UserService {
val userResposity by lazy { UserRepository() }
override fun login(userName: String, pwd: String) {
println("loading开始")
userResposity.login(userName, pwd).covert()
.execute(object : BaseObserver<LoginBean>() {
override fun onNext(t: LoginBean?) {
super.onNext(t)
println("登录成功")
}
})
}
}
3.1返回数据转换
/*
* 返回数据转换
*/
fun <T> Observable<BaseRep<T>>.covert():Observable<T>{
return this.flatMap(object :Function<BaseRep<T>,Observable<T>>{
override fun apply(t: BaseRep<T>): Observable<T> {
if(t.errorCode != 0){
return Observable.error(BaseException(t.errorCode,t.errorMsg))
}else{
return Observable.just(t.data)
}
}
})
}
3.2rx封装
/*
* Observable扩展
*/
fun <T> Observable<T>.execute(observer:BaseObserver<T>){
this.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer)
}
3.3错误处理
open class BaseObserver<T> : Observer<T> {
override fun onSubscribe(d: Disposable?) {
}
override fun onNext(t: T?) {
}
override fun onError(e: Throwable?) {
if(e is BaseException){
println(e.errorMsg)
}else{
val errorMsg = NetExceptionUtils.exceptionHandler(e!!)
println(errorMsg)
}
println("loading结束")
}
override fun onComplete() {
println("loading结束")
}
}
/**
* create by Admin in 2021/6/9
*
* @Description : 异常信息封装
**/
object NetExceptionUtils {
fun exceptionHandler(e: Throwable): String {
var errorMsg = "未知错误"
when (e) {
is UnknownHostException -> {
errorMsg = "网络不可用"
}
is SocketTimeoutException -> {
errorMsg = "请求网络超时"
}
is HttpException -> {
val httpException = e as HttpException
errorMsg = covertStatusCode(httpException)
}
is ParseException,
is JSONException -> {
errorMsg = "数据解析错误"
}
}
return errorMsg
}
private fun covertStatusCode(httpException: HttpException): String {
var msg = ""
when (httpException.code()) {
in 500 until 600 -> {
msg = "服务器处理请求错误"
}
in 400 until 500 -> {
msg = "服务器无法处理请求"
}
in 300 until 400 -> {
msg = "请求被重定向到其他界面"
}
else -> {
msg = httpException.message()
}
}
return msg
}
}
执行结果
D/OkHttp: {"data":null,"errorCode":-1,"errorMsg":"账号密码不匹配!"}
<-- END HTTP (66-byte body)
I/System.out: 账号密码不匹配!
loading结束
网友评论