使用更为安全的方式收集 Android UI 数据流

Android 运用中,通常需求从 UI 层搜集 Kotlin 数据流,以便在屏幕上闪现数据更新。一同,您也会期望经过搜集这些数据流,来防止发生不用要的操作和资源糟蹋 (包含 CPU 和内存),以及防止在 View 进入后台时泄露数据。

本文将会带您学习怎样运用 LifecycleOwner.addRepeatingJobLifecycle.repeatOnLifecycle 以及 Flow.flowWithLifecycle API 来防止资源的糟蹋;一同也会介绍为什么这些 API 合适作为在 UI 层搜集数据流时的默许挑选。

资源糟蹋

不管数据安全流出产者的详细结束怎样,咱们都 推荐 从运用的较底层级显露 Flow API。不过,您也应该保证数据流搜集操作的android的drawable类安全性。

运用一些现存 API (如 CoroutineScope.launch线程、Flow.launchIn 或 Lifeandroid下载cycleCoroutineScope.launchWhenX) 搜集根据 channel 或运用带有缓冲的操作符 (如 buffer、conflate、flowOn 或 shareIn) 的冷流的数据是 不安全的,除非您在 A安全ctivity 进入后台时手动吊线程池的七个参数销发动了协程的 Joandroid什么意思b。这些 API 会在内部出产者在kotlin是什么意思后台发送安全项目到缓冲区时坚持它们的生动状况,而这样一来就糟蹋了资源。

留神: 冷流 是一种数据流类型,这种数据流会在新的协程电话订阅android平板电脑价格者搜集数据时,按需实施出产者的代码块。

例如下面的比如中,运用 callbackFlow 发送方位更新的数据流:‍

// 根据 Channel 结束的冷流,能够发送方位的更新
fun FusedLocationPr线程池面试题oviderClient.locationFlow() = callbackFlow<Location> {
val callback = obje协程appct : Loc线程安全ationCallback() {
oveandroid软件开发rride fun onLocationResult(result: LocationResult?) {
re协程官网sult ?: return
try { offer(result.lastLocation) } catch(e: Exc线程池创立的四种eption) {}
}
}
rkotlin实战equestLocationUpdates(cr协程appeateLocationRequest(), callback, Looper.getMainLooper())
.addOnFailureLi协程游览stener { e ->
close(e) // 在出现异常时封闭 Flow
}
// 在 Flow 收android手机集结束时进行拾掇操作 
awaitClose {
removeLocationUpdatAndroides(callback)
}
}

留神: callbackFlow 内部运用 channel 结束,其概念与阻塞 队伍 非常类似,并且默许容量为 64。

运用任意前述 API 从 UI 层搜集此数据流都会导致其持续发送方位信息,即便视图不再展示数据也不会连续!示例如下:

class LocationActivity : AppCompatActiandroid竞赛专用包vity() {
override fun onCreate(savedandroid手机InstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 最早在 View  处于 STARTED 状况时从数据流搜集数据,并在
// 生命周期进入 STOPPED 状况时 SUSPENDS(挂起)搜集操作。
// 在 View 转为 DESTROYED 情android是什么手机牌子况时撤消线程的几种状况数据流的搜集操作。
life线程的几种状况cycleScop协程机票e.launchWhenStarted {
locationProvider.locationFlow().collect {
// 新的方位!更新地图
}
}
// 相同的问题kotlin为什么盛行不起来也存在于:协程游览
// - lifecycleScope.launch { /* 在这里从 locationFlow() 搜集数据 */ }
// - locationProvider.lo线程撕裂者cationFlAndroidow().onEach { /* ... */ }.launchIn(lifecycleScope)
}
}

lifecyclkotlin面试题eScope.la安全出产法unchWhenStarted 挂起了协程的实kotlin是什么意思行。虽然新的方位信息没有被处理,但 callbackFlow 出产者仍然会持续发送方线程池创立的四种位信息。运用 lifecy协程官网cleScope.launchlaunchIn API 会愈加危险,因为视图会持续消费方位信息,即便处于后台也不会连续!这种状况或许会导致您的运用溃散。

为了处理这些 API 所带来的问题,您需求在视图转入后台时手动撤消搜集操作,以撤消 callbackFlow 并防止kotlin下载方位供给者持续发送项目并糟蹋资源。举例来说,您能够像下面的比如这样操作:

class Locatiandroid下载安装onActivity : AppCompatActivity() {
// 方位的协程监听器
pri线程撕裂者vate var安全期是哪几天 locat线程安全ionUpdatesJob: Jo协程教育b? = null
override fun onStart() {
super.onStart()
locatio协程 线程nUpdatesJob = lifecycleScope.launch {
locationProvider.locationFlow().collect {
// 新的方位!更新地图。
}
}
}
override fun onStop()协程教育 {
// 在视图进入后台时连续线程池搜集数据
locationUpdatesJob?.canceandroid平板电脑价格l()
sAndroidup协程教育er.onStop()
}
}

这是一个不错的处理计划,美中不足的是有些冗长。假如这个国际有一android下载安装个有关 Android 开发者的普遍事实,那一定是咱们都不喜爱编写模版代码。不用编写模版代码的一个最大利益便是——写的代码越少,犯错的概率越小!

LifecycleOwner.addRepeatingJob

现在咱们境遇相协程官网同,并且也知道问题出在哪里,是时分找出一个处理计划了。咱们的处理计划需求: 1. 简略;2. 和睦或者说便于回想与理解;更重要的是 3. 安全!不管数据流的结束细节怎样,它都应能够应对所有用例。

刻不容缓——您应该运用的 API 是 lifecyclkotlin面试题e-runtandroid下载安装ime-ktx 库中所供给的 LifecycleOwner.addRepeatingJob。请参阅下面的代码:

class LocationActivity : AppCompakotlin下载tActkotlin教程ivity() {
overrkotlin语言ide fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 最早在 View  处于 STARTED 状况时从数据流搜集数据,并在
// 生命周期进入 STOPPED 状况时 STOPPED(间协程网断)搜集操作。
// 它会在生命kotlin怎样读周期再次进入 STARTED 状况时自动开始安全进行数据搜集操作。
lifecycleOwner.addR安全工程专业epeatingJob(Lifecycle.State.STARTED) {
locationProvider.locationFlow().collect {
// 新的方位!更新地图安全教育
}
}
}
}

addRepeatingJob 接纳 Lifecycle.State 作为参数,并android竞赛专用包用它与传入的代码块一同,在生命周期抵达该状况时,自动创立并发动新kotlin教程的协程;一同也会在生命周期低于该状况时撤消正在工作的协程安全工程专业

因为 addRepeatingJob 会在协程不再被需求时自动将其撤消,因而能够防止发生撤消操作相线程是什么意思关的模版代码。您或许现已猜到,为了防止意外行为,android手机这一 API 需求在 Activ协程官网ity 的 onCreate 或 Fragment 的 onViewCreated 办法中调用。下面是合线程安全作 Fragment 运用的示例:安全期是哪几天

class Loca线程池的七个参数tionFragmkotlin怎样读ent: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundl安全教育渠道e?) {
// ...kotlin语言
viewLifecycleOwner.addRepeatingJob(Lifecycle.State.STARTED) {
locationProvider.locationFlow().collect {
// 新的方位!更新地图
}
}
}
}

留神:线程安全 这些 API 在 lifecycle:lifecycle-runtime-ktx:2.4.0-alphakotlin语言01 库或其更新的版本中可用。

运用 repeatOnLifecycle

出于供给更为活络的 API 以及保存调安全教育用中的 CoroutineContext 的意图,咱们也供给了 挂起函数 Lifecycle.repeatOnLifecyc线程和进程的区别是什么le 供您运用。repeatOnLifecycle 会挂起调用它的协程,并会在进出政策状况时从头实施代码块,最终在 Lifecycle 进入毁掉状况时恢复调用它的协程。

假如您需求在重复作业前实施一次装备使命,一同期望使命能够在重复作业开始前坚持挂起,该 API 能够帮您结束这样的操作。示例如下:

class LocationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceSt线程池创立的四种ate)
lifecycleScope.launch {
// 单次装备使命
val expensiveObject = createExpensiveObject()
lifecycle.repeatOnL线程池面试题ifecycle(Lifecycle.安全State.STARTED) {
// 在生命周期进入 STARTED 状况时开始重复使命,在 STOPED 状况时连续
// 对 expensiveObject 进行kotlin下载操作
}
// 当协程恢复时,`lifecycle` 处于 DESTROY 状况。repeatOnLifecycle 会在
// 进入 DESTROYED 状况前挂起协程的实施
}
}
}

Flow.flowWithLifecycle

当您只需求搜集一个数据流时,也能够运用 Flow.flowWithLifecycle 操作符。这一 API 的内部也运用 suspend L线程安全ifecycle.repeatOnLifecycle 函数结束,并会在生命周期进入和脱离线程安全政策状况时发送项目和撤消内部的出产者。

class LocationActivi协程机票ty : AppCompatActikotlin面试题vity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceStatekotlin下载)
locat安全期计算器ionProvider.locationFlow()
.flowWithLifecycle(this, Lifecyclkotlin为什么盛行不起来e.State.STARTED)
.onEach协程官网 {
// 新的方位!更新地协程游览图
}
.launchIn(lifecycleScope)
}
}

留神: F安全出产法low.flowWithLifecycleandroid什么意思 APandroid下载安装I 的命安全出产月名以 Flow.flowOn(CoroutineContext) 为先例,因为它会在不影响下流数据流的一同批改搜集上游数据流的 CoroutineContext。与 flowOandroid竞赛专用包n 类似的另一点是,Fandroid下载安装low.flowWithLifecycle 也加入了缓冲区,以防止消费者无法跟上出产者。这一特征源于其结束中运用的 callbackFlow

装备内kotlin中心编程部出产者

即便您运用了这些 API,也要当心那些或许糟蹋资源的暖流,就算它们没有被搜集亦是如此!虽然针对这些暖流有一些合适的用例,可是仍要多加留神并在必要时进行记载。另一方面,在一些状况下,即便或许构成资源的糟蹋,令处于后台的内部数据流出产者坚持生动状况也会利于某些用例,如线程是什么意思: 您需求即时kotlin为什么盛行不起来改写可用数据,而不是去获取并暂时展示陈腐数据。您能够根据用例决议出产者是否需求kotlin中心编程一向线程安全处于生动状况

您能够运用 MutableStateFlowMutableSharedFlow 两个 API 中显露的 subscriptionCount 字段来控制它们,当该字段值为 0 时,内部的出产线程安全者就会连续。默许状况下,只需持有数据流实例的目标还在内存中,它们就会坚持出产者的生动状况。针对这些 API 也有一些合适的用例android什么意思,比如运用 StateFlowUiState 从 ViewModel 中露kotlin实战出给 UI。这么做Kotlin很合适,因为它意味着 ViewModel 总是需求向 View 供给最新的 UI 状况。

类似的,也能够为此类线程操作运用 同享开始战略 装备 Flow.stateIn 与 Flow.shareIn 操作符。While线程安全Subscribed() 将会在没有生动的订阅者时连续内部的出产者!相应的,不管数android平板电脑价格据流是 Eaandroid体系gerly (生动) 仍是 Lazily (慵懒)协程网订机票 的,只需它们运用的 Cor线程池的七个参数outineSckotlin语言ope 还处于生动状况,其内部的出产者就会坚持生动。

留神: 本文中所描绘的 API 能够很好的作为默许从 UI 搜集数据流的办法,并且不管数据流的结束办法怎样,都应该运用它们。这些 API 做了它们要做的事: 在 UI 于屏幕中不行见时,连续搜集其数据流。至于数据流是否应该线程的几种状况一向处于活动状况,则取决于线程和进程的区别是什么它的安全出产月结束。

在 Jetpack Compose 中安全地搜集数据流

Flow.collectAsState 函数能够在 Compose协程网线程池面试题搜集kotlin实战来自 comandroid平板电脑价格posable 的数据流协程官网,并能够android什么意思将值表明为 State,以便能够更新 Compose UI。即便 Compose 在宿主kotlin中心编程 Activity 或 Fragment 处于后台时不会协程网订机票重组 UI,数据流出产者仍会坚持生动并会构成安全工程专业资源的糟蹋。Compose 或许会遭受与 View 体系相同的问题。线程是什么意思

在 Compose 中搜集数据流时,能够运用 Flow.flowWithLifecycle 操作协程app符,示例如下:

@Composable
fun Loc线程ationScreen(locationFlow: Fandroid体系low<Flow>) {
val likotlin实战fecycleOwner = LocalLifecycleOwner.cukotlin为什么盛行不起来rrent
val locationFlowLifecycleAware = remember(locationFlow, lifecycleOwner) {
locationFlow.flowWithLifecycle(lifecycleOwner.lifec协程网订机票ycle, Lifecycle.State.STARTED)
}kotlin怎样读
val location by locationFlo线程是什么意思wLifecycleAware.collectAsState()
// 当时方位,能够拿它做一些操作
}

留神,您 需求记住 生命周期感知型数据流运用 locatioKotlinnFlow安全 lifecycleOwnekotlin极简教程r 作为键,以便一向运用同一个数据流,除非其间一个键发生改动。

Compose 的副作用 (Side-effect) 便是有必要处在 受控环境中,因而,运用 LifecycleOwner.a线程池ddRepeatingJob 不安全。作为代替,能够运用 LaunchedEffect 来创立随从 composable 生命周期的协程。在它的代码块中,假如您需求在宿主生命周期安全教育渠道登录进口处于安全某个 State 时从头实施一个代码块,能够调用挂线程池的七个参数起函数 Lifecycle.repeatOnLifecycle

对比 LiveData

您或许会觉得,这些 API 的表现线程池面试题与 LiveData 很类似——确实是这样!Li协程电话veData 能够感知 Lifecycle,并且它的重启行为使其非常合适查询来自 UI 的数据流。同理 LifecycleOwner.addRepeatingJobsuspend Lifecycle.repeatOnLife协程之窗cycle 以及 Flow.flowWithLifecycle 等 API 亦是如此。

在纯 Kotlin 运用中,运用这些 API 能够非常自然地代替 Liveandroid手机Daandroid竞赛专用包ta 搜集android是什么手机牌子数据流。假如您运用这些 API 搜集数据流,换成 Live安全出产月DaAndroidta协程 线程 (相对于运用协程和 Flow) 不会带来任何额外的利益。并且因为 Fl线程池面试题ow 能够从任何 Dispatcher 搜集数据,一同也能经过它的 操作符 取得更多功用,所以 Flow 也更为活络。相安全期计算器对而言,Live安全期是哪几天Data 的可用线程撕裂者操作符有限,且它总是从 UI 线程查询数据。

数据绑定对 StateFlow 的支撑

另一方面,您会想要运用 LiveData 的原因之一,或许是它遭到数据绑定的支撑。不过 StateFl安全出产月ow 也相同!更多有关数据绑定对 StateFlow 的支撑信息,请参阅 官方文档。

在 Android 开发中,请运用 LifecycleOwner.addRepeatinandroid平板电脑价格gJob协程官网suspend Lifecycle.repeatOnLikotlin中心编程fecycle Flow.flowWithLifecycle 从 UI 层安全地搜集数据流。

发表评论

提供最优质的资源集合

立即查看 了解详情