Learning Xamarin–Preserving State With JSON

By October 9, 2013Xamarin
[Please see the Table of Contents for this series.]

PassingVMToActivityIn a recent entry in this series, I discussed one approach to preserving state when the application is stopped.  I then received a tweet from my friend Paul Betts of GitHub.com saying “one thing that’s super useful is to use JSON.net to stuff off objects in the Bundle.”  Great idea.

Paul was kind enough to send a code snippet and from there I worked up an example.  Let’s review it together…

Begin by taking a look at this original posting on sending string data from one page to another.  In that posting I stashed the current date and time into the intent using PutExtra, and retrieved it in the second Activity by calling GetStringExtra. 

Here we’re going to do pretty much the same work, except this time instead of passing the time the button was clicked, as a string, we’re going to pass a ViewModel and then extract data from the VM in the receiving activity.  This is very cool, and once the pattern is established it greatly simplifies inter-Activity communication.

Create the App and the Layouts

Start by creating a new Android Application and name it PassingStateWithJason.  Delete the contents of the Layout folder and delete the Activity that is provided.  We’ll start by creating the first screen.  Right click on Layout and choose Add->New Item-> Android Layout. Name it First.axml.  Drag a button on and set the properties, or just copy the following code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click Me!" />
</LinearLayout>

 

While we’re at it, let’s create the second page, which we’ll call Second.axml.  For this one, drag on three TextView objects, or copy this markup:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="7dip"
android:text="Data Retrieved:" />
<TextView
android:id="@+id/Text1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/Text2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

That’s it for layout pages.  Now we need to add the logic. 

Getting the Json Library

Before we go any further, we’re going to need a Json library that works with Xamarin.  Easiest is to download it from the Xamarin Developer Center.  Click the Download button, unzip and look in Json.NET-4.5.11->lib->android.  Copy Newtonsoft.Json.DLL  to your project or to a known location.  Add a reference from your project to that library.

Creating the View Model

Let’s create a simple class that will stand in for a View Model that we might use in the MVVM pattern when creating our application. 

class MyViewModel
{
public string Name { get; set; }
public string State { get; set; }
}

Passing the View Model From One Activity To Another

Now we can work the logic for the first Activity. Right click on the project and choose Add->New Item->Activity (if you are in Visual Studio. In Xamarin Studio the menu choices are slightly different).  Call this FirstActivity.cs

We’re going to write two methods in FirstActivity.cs.  The first is an override of OnCreate and is exactly like the override we created in the earlier posting,

[Activity(Label = "Hello Android!",
MainLauncher = true, Icon = "@drawable/icon")] public class FirstActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.First);
var button = FindViewById<Button>(Resource.Id.Button);
button.Click += buttonClicked;
}

The second is the event handler buttonClicked.  Here we’re going to instantiate a MyViewModel  object and pass it, via the intent, to the second activity.

private void buttonClicked(object sender, EventArgs e)
{
var vm = new MyViewModel()
{ Name = "Jesse Liberty", State = "MA"};

var intent = new Intent(this, typeof(SecondActivity));
intent.PutExtra("ViewModel", JsonConvert.SerializeObject(vm));
StartActivity(intent);
}

Notice that we initialize our MyViewModel object with a Name and a State and we then call PutExtra on the intent, passing in the Key (ViewModel) and the object – in this case a Json serialized version of the ViewModel.  Because Json is just a string, this is both efficient and effective.

Create a second Activity and name it (appropriately) SecondActivity.cs.   Here we’ll just override OnCreate.  We can get the Extras from the Intent as an object and then pass the result of calling GetString on that object to JsonConvert’s DeserializeObject method, getting back a rehydrated instance of MyViewModel.  Once we have that object, we can extract the Name and State values from its properties,

[Activity(Label = "Second Activity")] public class SecondActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);

var intentBundle = Intent.Extras;
var vm = JsonConvert.DeserializeObject<MyViewModel>(
intentBundle.GetString("ViewModel"));

SetContentView(Resource.Layout.Second);
var text1 = FindViewById<TextView>(Resource.Id.Text1);
var text2 = FindViewById<TextView>(Resource.Id.Text2);
text1.Text = vm.Name;
text2.Text = vm.State;
}
}

We have successfully passed the ViewModel from the first Activity to the second as shown in the figure at the top.

 

About the Author

JesseJesse Liberty is a Master Consultant for Falafel Software, a Microsoft MVP, an author,  and he creates courses for Pluralsight.    Liberty hosts the popular Yet Another Podcast and his blog is considered required reading. He was a Senior Evangelist for Microsoft,  a XAML Evangelist for Telerik, a Distinguished Software Engineer at AT&T; Software Architect for PBS and Vice President of Information Technology at Citibank. Jesse can be followed on twitter at @JesseLiberty

The following two tabs change content below.