Where to put ViewModels on Android

217 views
Skip to first unread message

Cory Juhlin

unread,
Mar 3, 2015, 8:38:18 AM3/3/15
to reacti...@googlegroups.com
Hi all,

I am developing the Android version of an iPhone app that already uses ReactiveUI. One problem I am having with the Android version is the absolute chaos that occurs when the user rotates the screen. I understand the motivations and rationale for Android basically killing everything and restarting it, but it's causing some grief.

I was thinking about using a static/singleton object outside of the Android fragment/activity to "hold" currently-used view models. This would help me with two types of scenarios:

1. Activity with large dataset loaded from network could reuse populated view model on orientation change instead of recreating the view model and reloading the data.

2. Two activities that share the same view model can coordinate instead of reloading the data twice (e.g. I have an activity that displays a list of photos in a grid recyclerview. Tapping on a photo fires up a new "photo viewer" activity that lets the user pan/zoom the image as well as swipe between full-size images.)

I don't know how ReactiveObject works on a lower level though. Would this cause memory leaks because the first incarnation of an activity subscribes to some events on its view model and then is recreated on an orientation change? How do other people handle this issue?

Thanks!

paul....@gmail.com

unread,
Mar 3, 2015, 11:28:51 PM3/3/15
to reacti...@googlegroups.com, reacti...@googlegroups.com
This isn’t a good idea because it won’t save you from other activity changes like whenever you invoke an intent. Serialize / deserialize the ViewModel then if that still isn’t fast enough you can implement a version of your plan that uses globals as a cache (but still effectively lives s.t. the ViewModel has to be deserialized)

Paul



--
You received this message because you are subscribed to the Google Groups "ReactiveUI mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to reactivexaml...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ShaneN

unread,
Jul 18, 2015, 4:26:38 PM7/18/15
to reacti...@googlegroups.com
I realize this is old but figured I'd post my experience :-)   

Here's a few SO posts I found with some things people have done to handle screen rotation behaviors


I'm still kind of new with Android but my solution was to save the viewmodel into  a static variable that's part of the Activity

        protected override void OnSaveInstanceState(Bundle outState)
       
{
           
base.OnSaveInstanceState(outState);
           
MyViewModel = ViewModel;
       
}


Then when it comes back from a saved state

protected override void OnCreate (Bundle savedInstanceState)
{
 if (MyViewModel == null || savedInstanceState == null)
           
{
               
ViewModel = new CreateNewVM();
           
}
           
else
           
{
               
ViewModel = MyViewModel;
 
MyViewModel = null;
           
}


And then my case might be different then yours because I'm using a page adapter so in that I override

 public override Java.Lang.Object InstantiateItem(Android.Views.ViewGroup container, int position)
        {
            var fragment = (Fragment)base.InstantiateItem(container, position);
            ((CastFragmentToSomething)).ViewModel = ViewModel   //I did a cast here instead of just using IViewFor because the IViewFor.ViewModel doesn't throw a property change
}



And then there as the fragments get created I set the ViewModel that was retained between states


That's probably all a little bit hacky but it seems to be working fine :-) I've tested with tombstoning and rotating and everything seems to load up successfully.. My guess is that this solution isn't that great for cases when the process is in the background and android decides to come along and GC the statics because of memory pressure... But for the sole purpose of just staying operational when you rotate the screen it seems to work fine..

I think the prettier solution would be to just serialize the VM And then "Cache" what the large data load items are.... So probably just serialize the VM so it retains state and then using Akavache to hold the expensive data and re-saturate the VM in a pretty small amount of time.

But what I have above is working so I'll leave it until I get a random crash around some Life Cycle nuance of android I'm currently unaware of:-) 
Reply all
Reply to author
Forward
0 new messages