利用Retrofit+ViewModel+coroutines 打造自動根據生命週期取消的網絡請求

利用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)
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章