美文网首页Androidkotlin
Kotlin中的协程 - 协程与Retrofit结合使用

Kotlin中的协程 - 协程与Retrofit结合使用

作者: 盛世光阴 | 来源:发表于2021-08-22 13:40 被阅读0次

前言

Kotlin是一种在Java虚拟机上运行的静态类型编程语言,被称之为Android世界的Swift,在GoogleI/O2017中,Google宣布Kotlin成为Android官方开发语言

添加对应依赖

技术好久不用都生疏了,包括写的这些关于协程的博客,回头看看都是一头雾水,加油,多挤挤时间学习点新东西持续提升能力,知识迟早都是会用上的,本文只是用来使用Retrofit中对Coroutine的支持,并没有使用到Dagger依赖以及DataBinding等技术所以MVVM框架不是很完整,详细的MVVM框架可以参考这里
Android MVVM实现

 //okhttp
implementation("com.squareup.okhttp3:okhttp:4.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
//coroutine
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
//viewmodel
implementation "androidx.lifecycle:lifecycle-common-java8:2.3.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"

创建对应的Mode类以及Okhttp相关配置

这里使用到了测试的Get API
https://jsonplaceholder.typicode.com/todos/1

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

创建数据类

data class UserInfo(val userId: Long = 0, val title: String = "")

创建Okhttp以及Retrofit相关配置

object OkhttpClient {

    fun getOkhttpClient() = OkHttpClient.Builder()
        .addNetworkInterceptor(HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        })
        .build()
}
interface ApiService {
    @GET("/todos/1")
    fun getInfo(): Deferred<UserInfo>
}

切换到IO线程中调用API

object UserInfoRepo {

    val apiService = Retrofit.Builder()
        .baseUrl("https://jsonplaceholder.typicode.com")
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .addConverterFactory(GsonConverterFactory.create())
        .client(OkhttpClient.getOkhttpClient())
        .build()
        .create(ApiService::class.java)

    suspend fun getUserInfo() = withContext(Dispatchers.IO){
        apiService.getInfo()
    }
}

ViewModel类的创建

abstract class UserInfoViewModel : ViewModel() {
    abstract fun getUserInfo()
    abstract var userInfo: MutableLiveData<UserInfo>
    abstract var isShoeLoading: MutableLiveData<Boolean>
}

这里使用到了viewModelScope 作为协程的作用域方便管理,viewModelScope调度在Main线程,所以可以直接进行LiveData的刷新

class UserInfoViewModelImpl : UserInfoViewModel() {
    override var userInfo: MutableLiveData<UserInfo> = MutableLiveData()
    override var isShoeLoading: MutableLiveData<Boolean> = MutableLiveData()

    override fun getUserInfo() {
        viewModelScope.launch {
            isShoeLoading.value = true
            try {
                userInfo.value = UserInfoRepo.getUserInfo().await()
            } catch (e: Exception) {
                //TODO exception
            }
            isShoeLoading.value = false
        }
    }
}

UI相关类的创建

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>


    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".UserInfoActivity">

        <TextView
            android:id="@+id/tv_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/btn_get_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Get Info"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_info" />

        <ProgressBar
            android:visibility="gone"
            android:id="@+id/pb_loading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class UserInfoActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val viewModel = ViewModelProvider(this)[UserInfoViewModelImpl::class.java]

        viewModel.isShoeLoading.observe(this, Observer {
            findViewById<ProgressBar>(R.id.pb_loading).visibility =
                if (it == true) View.VISIBLE else View.GONE
        })

        viewModel.userInfo.observe(this, Observer {
            findViewById<TextView>(R.id.tv_info).text = it.title
        })

        findViewById<Button>(R.id.btn_get_info).setOnClickListener {
            viewModel.getUserInfo()
        }
    }
}

演示效果

演示.gif

欢迎关注Mike的简书

Android 知识整理

相关文章

网友评论

    本文标题:Kotlin中的协程 - 协程与Retrofit结合使用

    本文链接:https://www.haomeiwen.com/subject/tybciltx.html