title: Observe flow in a lifecylce save way
body: <p><strong>Situation</strong></p>
  <p>I do load quite some data and then create UI elements from it - I do this for testing only and that's where the problem occurred.</p>
  <p><strong>Problem</strong></p>
  <p>If I use <code>flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)</code> it happens that I observe some data when my fragment is not active anymore (after screen rotation, theme change and similar) =&gt; this leads to <code>context</code> being null exception. My current solution does not have that problem.</p>
  <p><strong>Current solution</strong></p>
  <p>Here's is what I do currently and this seems to work properly:</p>
  <pre><code>class MyFragment : Fragment {
  
      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
          super.onViewCreated(view, savedInstanceState)
  
          // Update UI based on a flow
          lifecycleScope.launch(Dispatchers.IO) {
              DataManager
                  .flowExercises()
                  .take(1)
                  .collect {
                  
                      // to be save, we check current lifecylce state here!
                      if (lifecycle.currentState &gt;= Lifecycle.State.STARTED) {
                          val views = it.map {
                              TextView(context).apply {
                                  text = it.exercise.name
                                  gravity = Gravity.CENTER_HORIZONTAL
                              }
                          }
  
                          withContext(Dispatchers.Main) {
                              views.forEach {
                                  ll.addView(it)
                              }
                          }
                      }
                  }
          }
      }
  }
  </code></pre>
  <p><strong>New solution - NOT WORKING</strong></p>
  <p>I'd like to switch to <code>flowWithLifecycle</code> but I can't get this working reliable. Here's what I tried:</p>
  <pre><code>class MyFragment : Fragment {
  
      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
          super.onViewCreated(view, savedInstanceState)
  
          // Update UI based on a flow
          lifecycleScope.launch(Dispatchers.IO) {
              DataManager
                  .flowExercises()
                  .take(1)
                  .flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)
                  // Mapping may need some time...
                  .map {
                      it.map {
                          TextView(context).apply {
                              text = it.exercise.name
                              gravity = Gravity.CENTER_HORIZONTAL
                          }
                      }
                  }
                  .collect {
                      withContext(Dispatchers.Main) {
                          views.forEach {
                              ll.addView(it)
                          }
                      }
                  }
          }
      }
  }
  </code></pre>
  <p><strong>Edit - final solution</strong></p>
  <pre><code>DataManager
      .flowExercises() // this is an IO operation and will be slow
      .map {
          // this is slow as well - we create many views for TESTING only
          // we check the context each time because during this phase the fragment can be destroyed
          it.map { data -&gt;
              // if the context is not available anymore, this fragment is not attached anymore
              // =&gt; no need to create further views, the result will be dropped anyway
              // =&gt; yes, this work may be done unnecessarily...
              context?.let {
                  TextView(it).apply {
                      text = data.exercise.name
                      gravity = Gravity.CENTER_HORIZONTAL
                  }
              }
          }
      }
      .flowOn(Dispatchers.IO) // above code will be running on IO thread
      .flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)
      .onEach { views -&gt;
          // we are in state started =&gt; it's save to touch the UI
          views.forEach {
              ll.addView(it)
          }
      }
      .flowOn(Dispatchers.Main) // above code will be running on main thread
      .launchIn(viewLifecycleOwner.lifecycleScope)
  </code></pre>