前言
Kotlin
是一种在Java
虚拟机上运行的静态类型编程语言,被称之为Android
世界的Swift
,在Google
I/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()
}
}
}
演示效果
欢迎关注Mike的简书
Android 知识整理