Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ViewLifecycleCoroutineScope #157

Closed
RBusarow opened this issue Jul 19, 2020 · 0 comments · Fixed by #158
Closed

ViewLifecycleCoroutineScope #157

RBusarow opened this issue Jul 19, 2020 · 0 comments · Fixed by #158
Labels
enhancement New feature or request
Milestone

Comments

@RBusarow
Copy link
Owner

Fragment's double lifecycle issue affects LifecycleCoroutineScope (Androidx's or Dispatch's) as well.

Consider this example from the official docs:

class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {
            val params = TextViewCompat.getTextMetricsParams(textView)
            val precomputedText = withContext(Dispatchers.Default) {
                PrecomputedTextCompat.create(longTextContent, params)
            }
            TextViewCompat.setPrecomputedText(textView, precomputedText)
        }
    }
}

Because the View lifecycle is odd, we either need to wait until onViewCreated in order to access it, or we need to use viewLifecycleOwnerLiveData. Using the former, the developer must use ordinary lifecycle callback functions in order to guarantee the View's existence. This is inconsistent with the rest of lifecycle coroutines, which could be executed from inside init { }.

The alternative approach of observing viewLifecycleOwnerLiveData seems better. It allows the use of init { }. Also, since onViewCreated must happen after onAttach(), this means that an AAC viewModel initialized via by viewModels may be accessed safely. This means we can write the following:

class MyFragment @Inject constructor(
  coroutineScope: MainImmediateCoroutineScope
) : Fragment {

  val viewModel: MyViewModel by viewModels()

  init {
    coroutineScope.withViewLifecycle  { // this: ViewLifecycleCoroutineScope
      // safely reference this directly inside the constructor because this will never invoke before onAttach
      viewModel.someFlow.onEach {
        // ...
      }.launchOnStart() // ViewLifecycleCoroutineScope-specific functions for lifecycle-aware collection of Flow
    }
  }
}
@RBusarow RBusarow added the enhancement New feature or request label Jul 19, 2020
@RBusarow RBusarow added this to the 1.0.0-beta04 milestone Jul 19, 2020
@RBusarow RBusarow modified the milestones: 1.0.0-beta04, 1.0.0 Oct 3, 2020
@RBusarow RBusarow added this to the 1.0.0-beta05 milestone Oct 28, 2020
@RBusarow RBusarow linked a pull request Oct 28, 2020 that will close this issue
@RBusarow RBusarow closed this as completed Nov 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant