Android Weekly Issue #480
Becoming a Xoogler
一个要离开Google的人的回忆文.
Coroutine builders
suspend的方法只能被suspend的方法调用, 正常的方法不能.
最初连接正常方法和suspend的这两个世界, 需要coroutine builder
.
有三个基本的coroutine builder
:
- launch
- runBlocking
- async
并行进行两个请求:
scope.launch {
val news = async {
newsRepo.getNews()
.sortedByDescending { it.date }
}
val newsSummary = async {
newsRepo.getNewsSummary()
}
view.showNews(
newsSummary.await(),
news.await()
)
}
coroutineScope
是一个suspend方法.
用法:
suspend fun main(): Unit = coroutineScope {
launch {
delay(1000L)
println("World!")
}
println("Hello,")
}
// Hello,
// (1 sec)
// World!
Dagger 2 complete tutorial for beginner
Dagger 2的教程.
还有个sample: https://github.com/nlgtuankiet/dagger-basic
图不错.
Jetpack Compose Side-Effects I — LaunchedEffect
LaunchedEffect — Launch a coroutine tied to the scope of the composable.
如果composable退出composition, 即不再在屏幕上显示, coroutine会取消自己.
这个例子:
@Composable
fun TimerScreen() {
LaunchedEffect(key1 = Unit, block = {
try {
startTimer(5000L) { // start a timer for 5 secs
println("Timer ended")
}
} catch(ex: Exception) {
println("timer cancelled")
}
})
}
旋转屏幕的时候会先取消再开始.
另一篇文章讲rememberCoroutineScope
: https://proandroiddev.com/jetpack-compose-side-effects-ii-remembercoroutinescope-76104d7ff09
Entity Extraction using Google’s ML Kit on Android
Google ML Kit的Entity Extraction API.
可以用来提取文字信息.
Pose estimation and classification on edge devices with MoveNet and TensorFlow Lite
姿态识别.
tensorflow的例子: https://github.com/tensorflow/examples/tree/master/lite/examples/pose_estimation/android
Working Towards Android App Excellence
- Make app quality a cross-organizational focus — not just an engineering concern
- Organize teams around features and/or app user journey stages
- Use the same devices your customers use
Unbundling the WindowManager
Jetpack的WindowManager: https://developer.android.com/jetpack/androidx/releases/window
和Framework中的WindowManager功能一样. 额外还支持了可折叠屏和Chrome OS.
Why Workflow?
Square为什么要做自己的application framework.
https://github.com/square/workflow-kotlin
Seamless account transfers with Block Store
Block Store API允许你的用户在换手机的时候在新设备上重新认证.
Block Store帮忙存储的是authentication token.
用户需要一个a device-to-device restore flow.
文档: https://developers.google.com/identity/blockstore/android
Measuring Render Performance with Jetpack Compose
如何测量Compose的性能?
他们做了一些实验, 拿了一些数据.
这里还有一个视频:
https://www.youtube.com/watch?v=eDcGrY_AVlw
Observing live connectivity status in Jetpack Compose
网络状态的观测.
直接查看:
/**
* Network utility to get current state of internet connection
*/
val Context.currentConnectivityState: ConnectionState
get() {
val connectivityManager =
getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return getCurrentConnectivityState(connectivityManager)
}
private fun getCurrentConnectivityState(
connectivityManager: ConnectivityManager
): ConnectionState {
val connected = connectivityManager.allNetworks.any { network ->
connectivityManager.getNetworkCapabilities(network)
?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
?: false
}
return if (connected) ConnectionState.Available else ConnectionState.Unavailable
}
流式观察:
@ExperimentalCoroutinesApi
fun Context.observeConnectivityAsFlow() = callbackFlow {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val callback = NetworkCallback { connectionState -> trySend(connectionState) }
val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, callback)
// Set current state
val currentState = getCurrentConnectivityState(connectivityManager)
trySend(currentState)
// Remove callback when not used
awaitClose {
// Remove listeners
connectivityManager.unregisterNetworkCallback(callback)
}
}
fun NetworkCallback(callback: (ConnectionState) -> Unit): ConnectivityManager.NetworkCallback {
return object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
callback(ConnectionState.Available)
}
override fun onLost(network: Network) {
callback(ConnectionState.Unavailable)
}
}
}
界面:
@ExperimentalCoroutinesApi
@Composable
fun connectivityState(): State {
val context = LocalContext.current
// Creates a State with current connectivity state as initial value
return produceState(initialValue = context.currentConnectivityState) {
// In a coroutine, can make suspend calls
context.observeConnectivityAsFlow().collect { value = it }
}
}
是这个代码库里的改动:
https://github.com/PatilShreyas/NotyKT
Supporting different screen sizes on Android with Jetpack Compose
支持多屏幕的探讨.
其实还是用xml里的尺寸然后dimenResource就好.
Code
- https://github.com/alashow/datmusic-android 音乐app, 多个modules.
- https://github.com/tensorflow/examples/tree/master/lite/examples/pose_estimation/android tensorflow的例子.