0%

简易MVVM网络请求框架(基于Kotlin实现)

简易MVVM网络请求框架(基于Kotlin实现)

使用kotlin以最少代码实现retrofit+okhttp的网络请求

retrofit+okhttp的初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
object ApiClient {
private val okHttpClient: OkHttpClient
private val retrofit: Retrofit

init {
val logger = HttpLoggingInterceptor()
if (BuildConfig.DEBUG) {
logger.level = HttpLoggingInterceptor.Level.BODY
} else {
logger.level = HttpLoggingInterceptor.Level.NONE
}
val cache = Cache(NicebuyApp.app.cacheDir, 10 * 1024 * 1024)
okHttpClient = OkHttpClient.Builder().run {
readTimeout(30, TimeUnit.SECONDS)
writeTimeout(60, TimeUnit.SECONDS)
addInterceptor(logger)
cache(cache)
build()
}
val gson = GsonBuilder()
.setLenient()
.create()
retrofit = Retrofit.Builder().run {
baseUrl("https://www.nicebuy.io")
addConverterFactory(GsonConverterFactory.create(gson))
client(okHttpClient)
build()
}
}

fun getRetrofit(): Retrofit {
return retrofit
}

fun getOkHttpClient(): OkHttpClient {
return okHttpClient
}
}

接口service定义

1
2
3
4
interface TestService {
@GET("/v1/user/info")
suspend fun getUserInfo(@Query("uid") uid: String): ApiResponse<UserInfo>
}

定义一个顶层函数callFromNet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
suspend fun <T> callFromNet(apiFunc: suspend () -> ApiResponse<T>): Resource<T> {
return try {
val result = apiFunc.invoke()
if (result.code == 0) {
Resource.success(result.data, result.code, result.status)
} else {
Resource.error(null, result.code, result.status)
}
} catch (error: HttpException) {
if (BuildConfig.DEBUG) error.printStackTrace()
handleError(error)
} catch (throwable: Throwable) {
if (BuildConfig.DEBUG) throwable.printStackTrace()
Resource.error(null, 0, throwable.message ?: throwable.toString())
}
}

private fun <T> handleError(error: HttpException): Resource<T> {
return Resource.error(null, error.code(), error.message())
}

Repo的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class TestRepo(val context: CoroutineContext) {
private val service: TestService = ApiClient.getRetrofit().create()

fun getUserInfo(uid: String): LiveData<Resource<UserInfo>> {
return liveData(context) {
emit(Resource.loading(null))
//emitSource(loadFromDb()) //你可以从数据库加载
val resource = callFromNet {
service.getUserInfo()
}
emit(resource)
}
}
}

ViewModel实现

1
2
3
4
5
6
7
8
9
10
11
class TestViewModel : ViewModel() {
private val testRepo = TestRepo(viewModelScope.coroutineContext)
private val _uidData = MutableLiveData<String>()
val userInfoData = _uidData.switchMap {
testRepo.getUserInfo(it)
}

fun setUserId(uid: String) {
_uidData.value = uid
}
}

那么activity里面的使用就很简单了

1
2
3
4
5
6
7
8
9
10
11
12
private val testViewModel : TestViewModel by viewModels()

private fun getUserInfo(uid: String) {
testViewModel.userInfoData.observe(this, Observer {
when (it.status) {
Status.SUCCESS -> TODO()
Status.ERROR -> TODO()
Status.LOADING -> TODO()
}
})
testViewModel.setUserId(uid)
}