你可能需要了解下的Android开发技巧(一)
callbackFlow {}
+debounce()
降频
假如当前要做一个实时搜索的功能,监听输入框动态输入的内容向服务器发起搜索请求,这不仅会增大服务器的压力,而且也会产生很多的无用请求。
比如其实你想搜索一个“android”
,但随着你在输入框中动态编辑,最多可能会向服务器发送7次请求,很明显前面6次请求都是属于无用请求(暂时不考虑模糊匹配的场景)。
这个时候我们就可以借助于callbackFlow{}
将输入框的动态输入转换成流,再借助debounce()
对流进行降频即可。关于对debounce()
的讲解,可以参考之前的文章:debounce()限流
fun test4(editText: EditText) {
lifecycleScope.launchWhenResumed {
callbackFlow {
val watcher = editText.doAfterTextChanged {
trySend(it?.toString() ?: "")
}
invokeOnClose {
editText.removeTextChangedListener(watcher)
}
}.debounce(200).collect {
//对于输入框中的内容向服务器发起实时搜索请求
}
}
}
判断当前是否为主进程
常见的业务场景中,可能我们会把Service
单独放一个进程处理,比如为了单独存放WebView
再或者专门开一个服务进程与服务器进行通信,这样当UI进程死掉,也能缓存最新的数据到内容和本地 。
但有时,Service
单独放一个进程处理,也会走Application
的初始化逻辑,比如初始化第三方SDK、获取某些资源等等,但这些可能是只有UI进程才需要,所以Service
进程初始化应该跳过这些逻辑。
所以我们需要判断当前的线程是否属于UI线程,可以利用UI进程的包名和进程名相同
的特性实现,代码如下:
fun isMainProcess(): Boolean =
getSystemService<ActivityManager>()?.let {
it.runningAppProcesses.find { info ->
info.pid == Process.myPid()
}?.let { res ->
res.processName == packageName
}
} ?: true
当我写完上面的代码之后,发现Application
竟然直接提供了一个获取当前进程名称的方法:
不过这个只有SDK28以上
才能使用,可以判断一下,SDK28以下用上面的代码判断,SDK28及以上用下面的代码判断:
fun isMainProcess2(): Boolean = packageName == getProcessName()
作者:长安皈故里
链接:https://juejin.cn/post/7136913350893502494
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
链接:https://juejin.cn/post/7136913350893502494
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。