Kotlin开发 协程的实践 Retrofit + 协程 + ViewModel

前言

  此篇博客讲解协程与Retrofit 的组合开发

  使用自定义GsonConverterFactory可以增加全局判断code

依赖

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0'//LifecycleScope

代码部分

接口

import com.example.myapplication.data.UserBean
import retrofit2.Response
import retrofit2.http.GET

interface HttpList {

    @GET("test/getName")
    suspend fun getNameData(): Response<UserBean>
}

ViewModel

class MainViewModel : ViewModel() {
    /**
     * 创建协程统一上下文
     */
    private val mJob = SupervisorJob()

    /**
     * 创建io协程
     */
    private val mIoScope = CoroutineScope(Dispatchers.IO + mJob)

    private val _user = MutableLiveData<Pair<Boolean, String?>>()
    public val user : LiveData<Pair<Boolean, String?>> = _user

    override fun onCleared() {
        super.onCleared()
        mJob.cancel()//取消正在请求网络接口的协程
    }

    private fun getHttpList(): HttpList {
        val retrofit = Retrofit.Builder()
                .baseUrl("http://mockjs.xiaoyaoji.cn/mock/1k8Ou7Sxyro/")
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        return retrofit.create(HttpList::class.java)
    }

    public fun getUserData() {
        mIoScope.launch {
            yield()
            val response = getHttpList().getNameData()
            if (response.isSuccessful) {
                //请求成功
                _user.postValue(Pair(true, response.body()?.name))
            } else {
                //请求失败
                _user.postValue(Pair(false, "网络异常,${response.errorBody().toString()}"))
            }
        }
    }
}

也可以使用viewModelScope的ViewModel,但是他需要导入依赖

    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
class MainViewModel : ViewModel() {
    private val _user = MutableLiveData<Pair<Boolean, String?>>()
    public val user : LiveData<Pair<Boolean, String?>> = _user

    private fun getHttpList(): HttpList {
        val retrofit = Retrofit.Builder()
                .baseUrl("http://mockjs.xiaoyaoji.cn/mock/1k8Ou7Sxyro/")
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        return retrofit.create(HttpList::class.java)
    }

    public fun getUserData(){
        viewModelScope.launch {
            postUserData()
        }
    }

    public suspend fun postUserData() = withContext(Dispatchers.IO) {
            yield()
            val response = getHttpList().getNameData()
            if (response.isSuccessful) {
                //请求成功
                _user.postValue(Pair(true, response.body()?.name))
            } else {
                //请求失败
                _user.postValue(Pair(false, "网络异常,${response.errorBody().toString()}"))
            }
    }
}

Activity

class MainActivity : AppCompatActivity() {
    private lateinit var  mViewModel :MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        initListener()

    }

    private fun initListener(){
        btn1.setOnClickListener { mViewModel.getUserData() }

        mViewModel.user.observe(this, Observer {
            if (it.first){
                btn1.text = it.second
            } else{
                Toast.makeText(this, it.second, Toast.LENGTH_SHORT).show()
            }
        })
    }
}
原文地址:https://www.cnblogs.com/guanxinjing/p/15608249.html