android使用协程
2020-11-01 本文已影响0人
zhufred
本文只说明协程怎么在android中使用,如果您对协程的概念,语法等不熟悉,请自行搜索学习。
1.添加协程依赖
当前最新版本1.3.9
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
2.实现BaseActivity
为了开发方便这里BaseActivity里实现协程,其他Activity都继承BaseActivity。
abstract class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(){
override fun onDestroy() {
super.onDestroy()
cancel()
}
}
如果您不想这样写个BaseActivity,当然也是可以的。一定 一定 一定 要记着在onDestory中取消协程,否则容易造成内存泄漏哦!
3.使用协程
在MainActivity中实现如图所示的功能。即下拉刷新并发发送网络请求,当所有请求都完成后刷新列表。
图片1.pngclass MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...省略其他代码
mRefreshView.setOnRefreshListener {
refreshBookChapters()
}
}
private fun refreshBookChapters() {
launch(Dispatchers.Main) {
val temps = arrayListOf<Deferred<List<Chapter>>>()
for (book in bookShelfList) {
val temp = async {
Api.getChapters(book,null)
}
temps.add(temp)
}
for (temp in temps){
temp.await()
}
adapter?.notifyDataSetChanged()
mRefreshView.isRefreshing = false
}
}
}
launch(Dispatchers.Main) 即启用一个协程,Dispatchers.Main说明改协程运行在UI线程上,即在该协程里可以直接操作UI。
async即并发的在IO线程进行网络请求。接下来我们看一下 Api.getChapters(book,null)是什么样子的
suspend fun getChapters(book: Book, isCache: ((url: String) -> Boolean)?): List<Chapter> = withContext(Dispatchers.IO) {
val result = arrayListOf<Chapter>()
val id = getSourceId(book.bookCUrl)
if (id != null) {
try {
val config = SourceManager.bookSourceConfigs[id]
val url = if (book.lastPageUrl.isNotEmpty()) book.lastPageUrl else book.chapterUrl
val dbListDeferred = async { ChapterDao.getChapters(book.id ?: "") }
val responseDeferred = async {
OkHttpClientManager.requestGet(url, config.charset)
}
val dbList = dbListDeferred.await()
val response= responseDeferred.await()
val list = HTMLParsing.getChapters(book, response.body, config)
//...省略相关业务代码
} catch (e: java.lang.Exception) {}
}
result
}
suspend修饰符 告诉编译器getChapters函数需要在协程中执行。withContext(Dispatchers.IO)说明了该方法运行与io线程。
到此这个简单的业务就完成了。