Android Jetpack: ViewModel


[JET BLAST] LYLA FUJIWARA: AtGoogle I/O 2017, we announced theLifecycle Library.

The Lifecycle Library is aset of libraries and guidance for avoiding memory leaksand solving common Android lifecycle challenges.

Now the LifecycleLibrary has hit 2.


It's part of Jetpack.

And it includes newintegrations with data binding.

This is a tour of the LifecycleLibrary's ViewModel class.

A ViewModel holdsyour app's UI data while survivingconfiguration changes.

Here's why that'sactually useful.

Rotating your phone isconsidered a configuration change.

Configuration changescause your whole activity to get torn downand then recreated.

If you don't properlysave and restore data from the destroyed activity, you may lose that data and end up with weirdUI bugs or even crashes.

So enter the ViewModel, which, of course, survives configuration changes.

Instead of storing all ofyour UI data in your activity, put it in the ViewModel instead.

Now, this helps withconfiguration changes, but it's also just generalgood software design.

One common pitfall whendeveloping for Android is putting a lot ofvariables, logic, and data into your activitiesand fragments.

This creates a large, unmaintainable mess of a class and violates the singleresponsibility principle.

You can use ViewModels to easilydivide out that responsibility.

The ViewModels will beresponsible for holding all of the data that you'regoing to show in your UI.

And then the activityis only responsible for knowing how to drawthat data to the screen and receiving user interactions, but not for processing them.

If your app loadsand stores data, I suggest making arepository class, as described in the “Guideto App Architecture.

” Make sure your ViewModeldoesn't become bloated with too many responsibilities.

To avoid this, you cancreate a presenter class or implement a more fullyfledged clean architecture.

OK, so to make aViewModel, you'll end up extendingthe ViewModel class.

And then you put yourUI-related instance variables that were previously in youractivity into your ViewModel.

Then in youractivity's onCreate, you get the ViewModel froma framework utility class called ViewModel Provider.

Notice the ViewModel Providertakes an activity instance.

This is themechanism that allows you to rotate the device, geta technically new activity instance, but always ensure thatactivity instance is associated with the same ViewModel.

With the ViewModelinstance, you can use Getters andSetters to access UI data from your activity.

If you want to modify thedefault constructor, which currently takesno parameters, you can use a ViewModel Factory tocreate a custom constructor.

Now, this is the simplestuse case of a ViewModel.

But the ViewModel class isalso designed to work well with LiveData and data binding.

Using all of these together, you can create a reactive UI, which is just a fancy way ofsaying a UI that automatically updates whenever theunderlying data changes.

This assumes all of yourdata in your ViewModel that you plan to show onscreen is wrapped in LiveData.

You then should set updata binding as normal.

Here's an exampleXML with the data binding layout tagand the variable tag for your ViewModel.

Then in youractivity or fragment, you associate the variables usedin the XML with the binding.

Here's an examplewith an activity.

There's one new line ofcode, setLifecycleOwner.

This allows the binding toobserve your LiveData objects in the ViewModel.

And it's essentiallythe magic that lets the binding updatewhenever the LiveData updates and the ViewModel's onscreen.

You can now directlyreference LiveData fields from your ViewModel in your XML.

If you combine thiswith binding adapters, you can move muchof the boilerplate logic out of your activity.

Note that this becameavailable at Android Studio 3.

1 and higher, so make sureyou're on the correct version.

To learn more, check outthe Introduction to LiveData in the docs.

OK, I'm going to finish offwith a few best practices.

First tip, you should neverpass contexts into ViewModels.

This means no passing infragments, activities, or views.

As you saw earlier, ViewModels can outlive your specific activityand fragment lifecycles.

Let's say that you store anactivity in your ViewModel.

When you rotate the screen, that activity is destroyed.

You now have a ViewModelholding a reference to a destroyed activity.

And this is a memory leak.

So if you find yourself needingapplication contexts, which outlive ViewModel lifecycles, use the Android ViewModel subclass instead.

This includes a reference tothe application for you to use.

OK, second tip.

ViewModels are meantto be used in addition to onSaveInstanceState.

ViewModels do notsurvive process shutdown due to resource restrictions.

But onSaveInstance bundles do.

ViewModels are great forstoring huge amounts of data.

onSaveInstanceStatebundles, not so much.

Use ViewModels to store asmuch UI data as possible so that that data doesn't needto be reloaded or regenerated during a configuration change.

onSaveInstanceState, on the other hand, should store thesmallest amount of data needed to restore the UI stateif the process is shut down by the framework.

So for example, you mightstore all of the user's data within the ViewModel but juststore the user's database ID in onSaveInstanceState.

Hopefully this has inspired youto try out the new ViewModel class in your appseither by itself or with the otherarchitecture components.

To learn more aboutusing ViewModels or any of the informationthat I just mentioned, check out thedocumentation below.


Leave A Reply

Your email address will not be published.