一、引言
开发 Android App,很多操作是耗时的,比如网络请求、数据库操作。这些任务如果不处理好,会卡住整个App。为了解决这个问题,Kotlin 协程提供了一种简单的方法来处理耗时操作。
本文会用简单讲解 Kotlin 协程的几个常用功能,比如
lifecycleScope.launch
、launchWhenResumed
和suspend
,通过例子帮助大家理解它们的用途。
二、lifecycleScope.launch
2.1 使用场景
lifecycleScope.launch
是 Android 开发中常用的协程启动方法,专门用于 Activity or Fragment 的生命周期绑定。它的主要优势在于,当生命周期结束时,协程会自动取消,避免内存泄漏。
2.2 基本用法
在 Activity or Fragment 中,使用 lifecycleScope
启动协程:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.*
class MainActivity : AppCompatActivity() {
private lateinit var tv: TextView
private lateinit var btn: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv = findViewById(R.id.textView)
btn = findViewById(R.id.button)
btn.setOnClickListener {
lifecycleScope.launch {
// 模拟后台任务在完成后更新UI
tv.text = getData()
}
}
}
suspend fun getData(): String {
delay(1000)
return "Hello Nimyears, Coroutines!"
}
}
协程会在User点击按钮时启动,getData()
模拟一个耗时任务,返回的数据会在 1 秒后更新到TextView
上。 虽然Activity
被销毁,协程会自动取消,避免潜在的内存泄漏。
2.3 结合 async
和并行任务
除了launch
,async
常和 lifecycleScope
配合使用,用于执行并行任务和返回结果:
lifecycleScope.launch {
val result1 = async(Dispatchers.IO) { performTask1() }
val result2 = async(Dispatchers.IO) { performTask2() }
val finalResult = result1.await() result2.await()
tv.text = finalResult
}
通过 async
,同时执行两个耗时任务(performTask1
和 performTask2
),最终结果在两者都完成后更新到 UI 上。
三、launchWhenResumed
3.1使用场景
LifecycleCoroutineScope
的一个扩展函数,用于确保协程只会在 Activity 或 Fragment 处于 resumed
状态时启动。在某些需要严格控制任务执行时机的场景中非常有用。
3.2的基本实现
代码语言:javascript复制class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
lifecycleScope.launchWhenResumed {
//只有在Activity恢复到resumed状态时才执行
performResumedTask()
}
}
private suspend fun performResumedTask() {
delay(500)
//执行一些只需在resumed状态下运行的逻辑
}
}
代码中介绍,协程在 Activity 的状态下运resumed
状态下运行,如果Activity 进入paused
状态,直到 Activity 再次恢复。
3.3 与生命周期的关系
该方法特别适合用在需要严格依赖生命周期的场景中,例如,某些网络任务或资源加载,只希望在 UI 可见时运行。如果Activity
被暂停或销毁,任务也会自动停止,确保不会浪费资源。
四、suspend
4.1 作用和实现
suspend
用于定义挂起函数。挂起函数不会阻塞线程,它会被挂起直到任务完成,这种机制特别适合用于处理耗时操作。
4.2 基本用法
代码语言:javascript复制suspend fun fetchData(): String {
delay(2000)
return "Fetched Data"
}
fun main() = runBlocking {
val data = fetchData()
println(data)
}
suspend
函数与普通函数不同,它必须在协程中调用(如 launch
orasync
),否则编译会报错。
4.3结合 withContext
切换线程
在处理耗时任务时,常常需要在不同的线程间切换。withContext
可以帮助我们简化这一过程:
suspend fun loadData(): String {
return withContext(Dispatchers.IO) {
"Loaded Data"
}
}
withContext
可以轻松切换到指定的线程执行任务,执行完成后会自动返回到调用协程的线程,比如 UI 线程。这种模式特别适用于需要后台加载数据在加载完成后更新 UI 的场景。
五、postValue
和 LiveData
5.1 作用和实现
postValue()
是LiveData
提供的一个用于在后台线程更新数据的功能。和setValue()
不同postValue()
可以异步更新值,避免在主线程中频繁调用可能导致的卡顿。
5.1postValue()
示例
代码语言:javascript复制class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> get() = _data
fun updateData() {
viewModelScope.launch {
val newData = fetchDataFromNetwork()
_data.postValue(newData)
}
}
private suspend fun fetchDataFromNetwork(): String {
delay(1000)
return "New Data"
}
}
在这个例子,ViewModel
中的协程会在后台获取数据,通过postValue()
异步更新LiveData
的值LiveData
观察者自动收到通知,更新 UI。
六、结论
Kotlin 协程是 Android 开发中的重要工具,简化异步任务的处理,避免复杂的回调机制。通过lifecycleScope.launch
和launchWhenResumed
,开发者可以轻松把协程与生命周期绑定,确保任务在合适的时间启动和取消。suspend
函数和withContext
提供了线程切换机制,帮助我们在不同线程间执行任务。
如果你看完文章觉得有用的请手动点赞,欢迎提问,谢谢大家的阅读 )