利用Retrofit+ViewModel+coroutines 打造自动根据生命周期取消的网络请求扩展函数
RetrofitViewModel
class RetrofitViewModel : ViewModel()
{
fun <T> add(
call: Call<T>,
onSuccess: ((result: T) -> Unit),
onFinally: (() -> Unit)? = null,
onFail: ((t: Throwable?) -> Unit)? = null,
)
{
viewModelScope.launch { execute(call, onSuccess, onFinally, onFail) }
}
private suspend fun <T> execute(
call: Call<T>,
onSuccess: ((result: T) -> Unit)? = null,
onFinally: (() -> Unit)? = null,
onFail: ((t: Throwable?) -> Unit)? = null,
) = withContext(Dispatchers.Default)
{
try
{
val response = call.execute()
if (response.isSuccessful)
{
val body = response.body()
if (body != null)
{
if (onSuccess != null)
{
viewModelScope.launch(Dispatchers.Main) { onSuccess.invoke(body) }
}
} else
{
if (onFail != null)
{
viewModelScope.launch(Dispatchers.Main) {
onFail.invoke(Exception("response.body() == NULL"))
}
}
}
} else
{
if (onFail != null)
{
viewModelScope.launch(Dispatchers.Main) {
onFail.invoke(Exception(response.message()))
}
}
}
} catch (e: Exception)
{
e.printStackTrace()
if (onFail != null)
{
viewModelScope.launch(Dispatchers.Main) {
onFail.invoke(e)
}
}
} finally
{
if (onFinally != null)
{
viewModelScope.launch(Dispatchers.Main) {
onFinally.invoke()
}
}
}
Unit
}
}
扩展函数
/**
* 使用协程的方式来网路请求,会根据生命周期自动取消
*/
inline fun <reified T> Call<T>.enqueue(
owner: ViewModelStoreOwner,
noinline onSuccess: ((result: T) -> Unit),
noinline onFinally: (() -> Unit)? = null,
noinline onFail: ((t: Throwable?) -> Unit)? = null,
)
{
val viewModel = ViewModelProvider(owner).get(RetrofitViewModel::class.java)
viewModel.add(this, onSuccess, onFinally, onFail)
}