问题

  • Android 是有生命周期的,在 UI 展示的时分可以承受一些数据更新 UI,在 App 进入后台的时分应该中止承受数据以便释放资源,而且避免一些意想不到的反常;
  • 协程和 Flow 是和 Android 渠道无关的 API,正常情况下无法感知 Android 生命周期方法;

处理计划

我们现在当然是有一些计划来处理上述问题,可能会有以下几种方法。

如何在 UI Layer 中安全地使用 Flow ?

方法一:手动取消 Job

Activity 方法:

如何在 UI Layer 中安全地使用 Flow ?

Fragment 方法:

如何在 UI Layer 中安全地使用 Flow ?

以上方法显然是比较麻烦的,有一些模板代码。

方法二:运用 repeatOnLifecycle 处理模板代码

Activity 方法:

如何在 UI Layer 中安全地使用 Flow ?

Fragment 方法:

如何在 UI Layer 中安全地使用 Flow ?

注:需求增加依靠 androidx.lifecycle:lifecycle-runtime-ktx

这种方法尽管处理了一些模板代码的问题,可是依然有多层嵌套的问题。

方法三:运用 flowWithLifecycle 处理多层嵌套

Activity 方法:

如何在 UI Layer 中安全地使用 Flow ?

注:此 API 是在 2.6.0-alpha01 版别中增加。

Fragment 方法类似,运用 flowWithLifecycle 即可。flowWithLifecycle 是新版中新增的一个扩展函数,实现方法如下:

如何在 UI Layer 中安全地使用 Flow ?

看上去是处理了嵌套的问题,可是并彻底,调查数据的操作还是需求在协程体中进行。

方法四:运用 collectWithLifecycle 彻底处理多层嵌套

如何在 UI Layer 中安全地使用 Flow ?

自定义扩展函数 collectWithLifecycle 实现大致如下:

如何在 UI Layer 中安全地使用 Flow ?

这个是我自己的一个扩展,官方库中并没有增加,不过我已经反馈给官方了。这种方法仅仅是处理了嵌套的问题,可是却躲藏了 Flow ,然后导致一系列的操作符将无法运用,不过这个在 UI Element/Compose 中并不是什么大问题。。

扩展阅览

处理 Android UI 的方法之外,Compose 本身也有相同的问题,官方也通过自定义扩展函数的方式增加了支撑,大致如下:

如何在 UI Layer 中安全地使用 Flow ?

本篇文章是依据本周一的 Android Dev Summit 2022 大会讲演收拾而得,更多相关内容见:

  • A safer way to collect flows from Android UIs
  • repeatOnLifecycle API design story
  • Consuming flows safely in Jetpack Compose