利用Retrofit+ViewModel+coroutines 打造自动根据生命周期取消的网络请求扩展函数

321 阅读1分钟

利用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)
}