Android Weekly Issue #417
Getting Started with the Motion Editor in Android Studio 4.0
Android Studio 4.0的Motion Editor使用.
How to run an expensive calculation with Kotlin Coroutines on the Android Main Thread without freezing the UI
关于协程的小实验.
代码在: https://github.com/LukasLechnerDev/Kotlin-Coroutine-Use-Cases-on-Android
是其中的UseCase#17.
- 正确:
Dispatchers.Default
: CPU intensive work. 线程池. UI线程不被阻塞.
private suspend fun calculateFactorialOnDefaultDispatcher(number: Int): BigInteger =
withContext(Dispatchers.Default) {
var factorial = BigInteger.ONE
for (i in 1..number) {
factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
}
factorial
}
- 错误: 在主线程直接做计算: 主线程被阻塞, progress bar没显示, Log出现丢帧报告.
private fun calculateFactorialInMainThread(number: Int): BigInteger {
var factorial = BigInteger.ONE
for (i in 1..number) {
factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
}
return factorial
}
- 另一个有趣的case:
private suspend fun calculateFactorialInMainThreadUsingYield(number: Int): BigInteger {
var factorial = BigInteger.ONE
for (i in 1..number) {
yield()
factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
}
return factorial
}
在主线程, 但是通过yield()
不断地让出, 让主线程可以进行其他任务.
现象: 显得不阻塞, 但是慢很多.
解释: 例子中使用了viewModelScope
, 使用的是Dispatchers.Main
, 会使用Handler发送消息, 当yield()
的时候, 协程挂起, HandlerDispatcher.kt 中的dispatch()
方法会被调用.
Concurrency VS Parallelism
- Concurrency: 同一个线程但是交替进行. 所以耗时长.
- Parallelism: 在不同的线程同时进行.
yield()
的另一个作用: 会检查协程是否取消.
Moving and swiping with RecyclerView
给RecyclerView加滑动和移动操作:
用ItemTouchHelper
private val simpleItemTouchCallback =
object : ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT
) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
// [3] Do something when an item is moved
val adapter = recyclerView.adapter
val from = viewHolder.adapterPosition
val to = target.adapterPosition
// [4] Keep up-to-date the underlying data set
Collections.swap(tasks, from, to)
// [5] Tell the adapter to switch the 2 items
adapter?.notifyItemMoved(from, to)
return true
}
override fun onSwiped(
viewHolder: RecyclerView.ViewHolder,
direction: Int
) {
// [6] Do something when an item is swiped
}
override fun clearView(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
) {
super.clearView(recyclerView, viewHolder);
// [7] Do something when the interaction with an item
// is complete
}
}
注意Kotlin中的二进制操作|
写作or
.
设置给RecyclerView:
ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(recyclerView)
Introducing GraphQL Kotlin Client
和GraphQL的server通信, 用普通的POST请求也可以, 但是容易出错, 所以不同语言有不同的clients:
https://graphql.org/code/#graphql-clients
本文介绍:
https://github.com/ExpediaGroup/graphql-kotlin
会生成client code, 具体使用看原文.
Android MVI with Kotlin Coroutines & Flow
用Kotlin协程实现的MVI.
Coroutines: Suspending State Machines
协程是如何工作的.
Further reading: The suspend modifier — Under the hood
本期还有一篇讲suspend方法的文章: What is suspend function in Kotlin Coroutines?
Android storage use cases and best practices
Android官方文档, 有关Android 10的scoped storage应用场景和best practices.
Code
帮助管理屏幕状态: https://github.com/RedMadRobot/state-delegator
一个生成DSL的插件: https://github.com/Hariofspades/dsl-api-generator
网友评论