新活动的对象序列化

Gar*_*rry 5 serialization android bundle android-activity xamarin

我正在使用Xamarin进行编码,我需要将一个对象传递给另一个活动,但是我在将对象转换为'Android.OS.Bundle'方面遇到错误

以下是错误:

'Android.Content.Intent.PutExtra(string,Android.OS.Bundle)'的最佳重载方法匹配有一些无效的参数

错误CS1503:参数2:无法从'SimpleMapDemo.TestObjectToSerialize'转换为'Android.OS.Bundle'

这是我用来将对象传递给另一个活动的代码:

TestObjectToSerialize testObjectToSerialize;
testObjectToSerialize.testString = "objectToSerialize";
Intent intent = new Intent (this.ApplicationContext, typeof(HomeScreen));
intent.PutExtra("objectToSerialize", testObjectToSerialize);
Run Code Online (Sandbox Code Playgroud)

这是班级:

[Serializable]
class TestObjectToSerialize
{
    public string testString{ set; get;}
}
Run Code Online (Sandbox Code Playgroud)

我可以请一些帮助来使这段代码有效吗?

提前致谢

Yur*_*lov 0

你有很多方法可以做到这一点。首先,我建议不要将该对象作为额外的对象传递。相反,您可以使用“单例模式” - 只需定义具有与您要传递的类型相同的静态属性的静态类,然后将传递对象分配给该静态属性。但如果您确实需要将其作为额外传递,则可以使用序列化并序列化为任何类型的对象。这是一个快速示例(注意,为了简化示例,我没有关闭流,也没有进行代码重用 - 这只是一个示例,以便您可以理解其原理)。在我的“MainActivity”中的某个按钮单击事件中,我添加了以下代码:

var testObj = new TestObjectToSerialize();
testObj.testString = "testString";
var formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, testObj);

var secondActivity = new Intent(this, typeof(SecondActivity));
secondActivity.PutExtra("testObj", stream.ToArray());
StartActivity(secondActivity);
Run Code Online (Sandbox Code Playgroud)

在 SecondActivity 中,我收到如下额外内容:

var byteArr = Intent.GetByteArrayExtra("testObj");
var stream = new MemoryStream(byteArr);
var formatter = new BinaryFormatter();
var testObj = formatter.Deserialize(stream) as TestObjectToSerialize;

Toast.MakeText(this, testObj.testString, ToastLength.Long).Show();
Run Code Online (Sandbox Code Playgroud)

您可以在此处使用任何类型的序列化。您还可以实施Java.IO.ISerializable. 首先,添加Mono.Android.Export.dll到您的项目参考中。现在,在您的TestObjectToSerialize添加中使用:

using Java.Interop;

现在像这样修改你的类:

public class TestObjectToSerialize : Java.Lang.Object, Java.IO.ISerializable
{
    public string testString { set; get; }

    //The magic starts here

    public TestObjectToSerialize()
    {
        Console.WriteLine("TestObjectToSerialize..ctor");
    }

    //You have to make this one
    public TestObjectToSerialize(IntPtr handle, JniHandleOwnership transfer)
        : base(handle, transfer)
    {
        Console.WriteLine("TestObjectToSerialize..ctor(IntPtr, JniHandleOwnership)");
    }

    [Export("readObject", Throws = new[] {
    typeof (Java.IO.IOException),
    typeof (Java.Lang.ClassNotFoundException)})]
    private void ReadObjectDummy(Java.IO.ObjectInputStream source)
    {
        testString = ReadNullableString(source);
    }

    [Export("writeObject", Throws = new[] {
    typeof (Java.IO.IOException),
    typeof (Java.Lang.ClassNotFoundException)})]
    private void WriteObjectDummy(Java.IO.ObjectOutputStream destination)
    {
        WriteNullableString(destination, testString);
    }

    static void WriteNullableString(Java.IO.ObjectOutputStream dest, string value)
    {
        dest.WriteBoolean(value != null);
        if (value != null)
            dest.WriteUTF(value);
    }

    static string ReadNullableString(Java.IO.ObjectInputStream source)
    {
        if (source.ReadBoolean())
            return source.ReadUTF();
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,MainActivity你可以这样做:

var testObj = new TestObjectToSerialize();
testObj.testString = "testString";

var secondActivity = new Intent(this, typeof(SecondActivity));
secondActivity.PutExtra("testObj", testObj);
StartActivity(secondActivity);
Run Code Online (Sandbox Code Playgroud)

SecondActivity此:

var testObj = Intent.GetSerializableExtra("testObj") as TestObjectToSerialize;
Toast.MakeText(this, testObj.testString, ToastLength.Long).Show();
Run Code Online (Sandbox Code Playgroud)

祝你好运=)