Office Hours — Today, April 22

Tuesday, April 20

Apr 22
7:20 PM
Mark M.
has entered the room
7:25 PM
Mark M.
turned on guest access
8:05 PM
Eric
has entered the room
Eric
Mark nice to see you
Mark M.
hello, Eric!
how can I help you this evening?
(assuming that it is evening where you are!)
Eric
What is the advantage of using viewLifecycleOwner instead of this when observing a livedata? ViewLifeCycleOwner is only available once a view is inflated so if I go back to my fragment I will always observe the livedata again
8:10 PM
Mark M.
you should choose a lifecycle that matches what you are trying to do with the observed data
so, for example, suppose that you want to use the observed data to update the UI of the fragment
for that, you should use viewLifecycleOwner, as otherwise you might be handed data when you have no UI to update
viewLifecycleOwner is tied to the lifecycle of the views -- onCreateViwe() and onDestroyView()
if, on the other hand, you do not want to update the UI of a fragment based on the LiveData, then using `this` for the lifecycle may be reasonable, if unusual
Eric
you make a good point. I was about to complain about observing the data twice using viewLifeCycleOwner inside of onCreateView but then I realized that the naviation component uses "replace" to navigate between fragments. Replace will remove and add a fragment, destroying its view. So it seems to be working as intended, once I go back to my fragment my view needs to be created again, and I want to fill it with the contents of my livedata
8:15 PM
Mark M.
that sounds about right, though I haven't poked at the guts of Navigation to know exactly what sort of FragmentTransaction it uses
Eric
are you familiar with the SingleLiveEvent class? I read an article saying it is an observer that fires once instead of twice. So in our scenario on back press our observer would not be notified a second time
Mark M.
there isn't a class like that in the Android SDK, though it is easy enough to create
basically, the single live event pattern has you use a LiveData<Event<T>> instead of a LiveData<T>
Eric
I'm trying to understand when to use a livedata vs a specific SingleLiveEvent (practically)
Mark M.
mostly, it is for configuration changes
suppose we have a fragment with a viewmodel
the viewmodel loads some data from somewhere for the fragment to display
8:20 PM
Mark M.
for that, we use LiveData<T>, so that if we undergo a configuration change, the new fragment instance gets the old viewmodel and is immediately handed whatever is already in the LiveData<T> when it starts to observe it
so, the fragment can immediately display the cached data
however, let's suppose that the data-load process could fail, such as having some sort of network error in a Web service call
and the product designers said "in case of an error, show a dialog"
one approach says that the viewmodel emits the error information in a LiveData<T>, and the fragment observes that to show the dialog
and, suppose that you elect to use a DialogFragment for that dialog
now, after a configuration change, you wind up with two overlapping dialogs
Android recreates the DialogFragment automatically, so you get its dialog
and, your primary fragment gets recreated, observes the LiveData<T> again, gets the error information, and shows another DialogFragment
the technical term for this is: "bad" :-)
what we *really* want is a guaranteed one-shot delivery mechanism, so we know that our error information is consumed exactly once, not more than once (and not accidentally dropped on the floor while a configuration change is in progress)
the Jetpack doesn't really have one of these :-(
so, Google developer relations folks came up with the single live event pattern: LiveData<Event<T>>
your fragment, after the configuration change, still gets the data handed to it again automatically... but the job of Event is to track that the data was already used once, so you do not try using it again
8:25 PM
Mark M.
in Kotlin with coroutines, we would use a Channel instead
or, with RxJava, we would use a PublishSubject
both of those need extra attention from a lifecycle management standpoint, but otherwise they do not cache results the way that LiveData does
you can see an implementation and discussion of the single live event pattern in *Elements of Android Jetpack*
Eric
on a rotation change why does android create 2 dialogs? Doesnt the first dialog get destroyed instead
Mark M.
a DialogFragment automatically recreates its dialog
and Android recreates the DialogFragment after the configuration change
now, one solution is to simply not use the DialogFragment, and to manage the dialog more directly yourself
for the dialog case, that can work
8:30 PM
Eric
does a DialogFragment work differently from a DialogFragment, because a fragment gets destroyed on rotation unless you retain it
Fragment
Mark M.
active fragments (those attached to an activity) get destroyed and recreated on a configuration change
Eric
a DialogFragment work differently from a Fragment
Mark M.
both DialogFragment and Fragment get destroyed and recreated on a configuration change
Eric
correct, so I thought it would get destroyed and recreated instead of resulting in 2 dialogs
Mark M.
except that your original Fragment created another DialogFragment in response to getting the LiveData emission again
Eric
I'll try to create an app to test your scenario. I appreciate it :)
Eric
has left the room
Mark M.
turned off guest access

Tuesday, April 20

 

Office Hours

People in this transcript

  • Eric
  • Mark Murphy