Alexander Fernandez
Alexander Fernandez

Reputation: 80

Get an object result from an activity in Xamarin with Visual Studio

I want to receive an object back from a child activity in Xamarin with Visual Studio 2015:

[Serializable]
class MyObj
{
    public string value { get; }

    public MyObj(string v)
    {
        value = v;
    }
} 

Child Activity

Intent myIntent = new Intent (this, typeof(FirstActivity));
MyObj obj = new MyObj("message");
myIntent.PutExtra ("obj", obj);                                        // cannot convert "obj" to Bundle
SetResult (Result.Ok, myIntent);
Finish();

FirstActivity

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    if (requestCode == 0)
        if (resultCode == Result.Ok) {
            var helloLabel = FindViewById<TextView> (Resource.Id.helloLabel);
            MyObj obj = data.GetSerializableExtra("obj") as MyObj;
            helloLabel.Text = obj.Text.ToString();
        }
    }
}

This code causes an error cannot convert obj to Bundle. I've also tried to implement Java.IO.ISerializable is MyObj but I couldn't get a right implementation. It always throws System.NotSupportedException: Unable to activate instance of type MyApp.MyObj from native handle 0x10001d (key_handle 0x1a027cb)

class Object1 : Java.Lang.Object, Java.IO.ISerializable
{
    public string value { get; }
    public Object1(string v)
    {
        value = v;
    }
}

I would like to get some advice. I'm new in Xamarin and I'm working with Visual Studio 2015

Upvotes: 1

Views: 1043

Answers (2)

Sven-Michael St&#252;be
Sven-Michael St&#252;be

Reputation: 14750

I'd always go for Parcelable. It's very fast! (10x faster) http://www.developerphil.com/parcelable-vs-serializable/

Here is how you implement it in Xamarin:

public class MyObj : Java.Lang.Object, IParcelable
{
    public string Value { get; set; }

    public MyObj()
    {
    }

    private MyObj(Parcel parcel)
    {
        // read your values in order
        Value = parcel.ReadString();
    }

    public void WriteToParcel(Parcel dest, ParcelableWriteFlags flags)
    {
        // read your values in order
        dest.WriteString(Value);
    }

    // -- stuff below here is needed from the parcel interfaces/mechanism --

    [ExportField("CREATOR")]
    public static MyObjCreator InitializeCreator()
    {
        return new MyObjCreator();
    }

    public class MyObjCreator : Java.Lang.Object, IParcelableCreator
    {
        public Java.Lang.Object CreateFromParcel(Parcel source)
        {
            return new MyObj(source);
        }

        public Java.Lang.Object[] NewArray(int size)
        {
            return new MyObj[size];
        }
    }

    public int DescribeContents()
    {
        return 0;
    }
}

SetResult

Intent myIntent = new Intent(this, typeof(FirstActivity));
MyObj obj = new MyObj {Value = "Hello"};
myIntent.PutExtra("obj", obj);
SetResult(Result.Ok, myIntent);
Finish();

OnActivityResult

var x = (MyObj)data.GetParcelableExtra("obj");

Upvotes: 1

Milen
Milen

Reputation: 8867

Passing complex objects is a bit tricky. You can use libraries like Json.Net to serialize to string before sending, and then deserialize on the other end.

myIntent.PutExtra ("obj", JsonConvert.SerializeObject(obj));

//in your receiving activity OnActivityResult...

var objectAsString = intent.GetStringExtra("obj")
var result = JsonConvert.DeserializeObject<MyObject>(objectAsString)

Nice and easy solution and well performing too..

Upvotes: 0

Related Questions