【问题标题】:Passing custom object between Android activities in C#在 C# 中的 Android 活动之间传递自定义对象
【发布时间】:2013-10-01 13:35:28
【问题描述】:

我正在使用 Xamarin.Android 在 VS2012 中创建一个 android 应用程序。我在主屏幕中显示自定义列表。当用户单击列表项时,我需要将此 Main 活动中的自定义对象(具有 ID、String、String、String 属性)传递给另一个。

谁能帮我举个例子?

编辑:

我已经尝试过other question中提到的解决方案

但问题是我遇到了异常:

这就是我在第二个活动中提取的方式

InsuranceReminderBO i = (InsuranceReminderBO)Intent.GetSerializableExtra("SelectedItemID");

i 为空

第一个活动设置中是这样的:

Intent intent = new Intent(this, typeof(ReminderDetails));

intent.PutExtra("SelectedItemID", selectedInsurance);

StartActivity(typeof(ReminderDetails));

class InsuranceReminderBO 定义为

public class InsuranceReminderBO : Java.Lang.Object, Java.IO.ISerializable

我也尝试过使用IParcelable,但我得到了错误Creator is not defined in ICreator or Creator

在CustomObject上实现Iparcelable

'public class InsuranceReminderBO : Java.Lang.Object, IParcelable
    {
        public InsuranceReminderBO()
        {
        }

        #region Objects and Properties
        private int id;
        private String strCompanyName;
        private String strPremiumAmount;
        private String stDueDate;

        public int ID
        {
            get { return this.id; }
            set { this.id = value; }
        }

        public String Company_Name
        {
            get { return this.strCompanyName; }
            set { this.strCompanyName = value; }
        }

        public String Premium_Amount
        {
            get { return this.strPremiumAmount; }
            set { this.strPremiumAmount = value; }
        }

        public String Due_Date
        {
            get { return this.stDueDate; }
            set { this.stDueDate = value; }
        }
        #endregion

        #region IParcelable implementation

        // The creator creates an instance of the specified object
        private static readonly GenericParcelableCreator<InsuranceReminderBO> _creator 
            = new GenericParcelableCreator<InsuranceReminderBO>((parcel) => new InsuranceReminderBO(parcel));

        [ExportField("CREATOR")]
        public static GenericParcelableCreator<InsuranceReminderBO> GetCreator()
        {
            return _creator;
        }

        // Create a new SelectListItem populated with the values in parcel
        private InsuranceReminderBO(Parcel parcel)
        {
            ID = parcel.ReadInt();
            Company_Name = parcel.ReadString();
            Premium_Amount = parcel.ReadString();
            Due_Date = parcel.ReadString();
        }

        public int DescribeContents()
        {
            return 0;
        }

        // Save this instance's values to the parcel
        public void WriteToParcel(Parcel dest, ParcelableWriteFlags flags)
        {
            dest.WriteInt(ID);
            dest.WriteString(Company_Name);
            dest.WriteString(Premium_Amount);
            dest.WriteString(Due_Date);
        }

        // Closest to the 'Java' way of implementing the creator
        /*public sealed class SelectListItemCreator : Java.Lang.Object, IParcelableCreator
        {
            public Java.Lang.Object CreateFromParcel(Parcel source)
            {
                return new SelectListItem(source);
            }

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

        #endregion
    }

#region GenericParcelableCreator
    /// <summary>
    /// Generic Parcelable creator that can be used to create objects from parcels
    /// </summary>
    public sealed class GenericParcelableCreator<T> : Java.Lang.Object, IParcelableCreator
        where T : Java.Lang.Object, new()
    {
        private readonly Func<Parcel, T> _createFunc;

        /// <summary>
        /// Initializes a new instance of the <see cref="ParcelableDemo.GenericParcelableCreator`1"/> class.
        /// </summary>
        /// <param name='createFromParcelFunc'>
        /// Func that creates an instance of T, populated with the values from the parcel parameter
        /// </param>
        public GenericParcelableCreator(Func<Parcel, T> createFromParcelFunc)
        {
            _createFunc = createFromParcelFunc;
        }

        #region IParcelableCreator Implementation

        public Java.Lang.Object CreateFromParcel(Parcel source)
        {
            return _createFunc(source);
        }

        public Java.Lang.Object[] NewArray(int size)
        {
            return new T[size];
        }
        #endregion
    }
#endregion'

我将对象置于意图中

InsuranceReminderBO selectedInsurance = listOfInsurance[e.Position];
Intent intent = new Intent(this, typeof(ReminderDetails));
            intent.PutExtra("SelectedItem", selectedInsurance);

在第二个活动中阅读

InsuranceReminderBO i = (InsuranceReminderBO)Intent.GetParcelableExtra("SelectedItem");

但将 i 设为 null。

【问题讨论】:

  • 如果您将 IParcelable 代码发布给您,我们也可以看到问题所在。
  • @SpiritMachine 请看我上面的编辑。
  • 那么您有 JSON 序列化的有效解决方案吗?如果没有,您能否发布您使用 IParcelable 获得的 Null 引用的堆栈跟踪?
  • @SpiritMachine no JSON 序列化对我不起作用,但经过大量谷歌搜索后,我找到了自己问题的答案。

标签: c# android xamarin.android xamarin


【解决方案1】:

要在 servicestack.text 解决方案上涂上尾巴,您只需下载 android DLL 并将它们引用到您的解决方案中。您可以使用它并将其添加到您的解决方案中,单独构建它,作为替代方案。 https://github.com/ServiceStack/ServiceStack.Text/tree/master/src/ServiceStack.Text.Android

我还使用了几种方法来来回转换可能有用的项目,试试

static public string ToJSON(this object item)
{
  var myval = JsonSerializer.SerializeToString(item);
  return myval;
}
static public T FromJSON<T>(string code)
{
   var item = JsonSerializer.DeserializeFromString<T>(code);
   return item;
}

【讨论】:

  • 谢谢。一段时间后它让我印象深刻,但我已经使用 StartActivity(intent) 实现了 IParcelable 并且它正在工作....可能在我的下一个阶段或项目中我将使用 jsonserializer...谢谢您的帮助...
【解决方案2】:

有一篇关于在 Xamarin here 中使用 IParcelable 的文章。

就我个人而言,我一直只是序列化为 JSON,额外传递一个字符串并在另一端反序列化它。

如果您使用我喜欢的ServiceStack.Text,您可以这样做:

intent.PutExtra("SelectedItemId", JsonSerializer.SerializeToString(selectedInsurance));

在另一端:

var insurance = JsonSerializer.DeserializeFromString<InsuranceReminderBO>(Intent.GetStringExtra("SelectedItemId"))

无需实现Java.Lang.Object, Java.IO.ISerializable

【讨论】:

  • 我尝试了 dan.clark 的解决方案。但是在反序列化时,我得到了空引用错误。以及我必须为 [JsonSerializer] 添加什么命名空间或引用???
  • 它在 ServiceStack.Text 中。您也可以使用 JSON.NET - 语法会略有不同,但大致相同。
  • 我尝试下载 ServiceStack.Text 但出现以下错误安装包:无法安装包“ServiceStack.Text 3.9.63”。您正在尝试将此包安装到以“MonoAndroid,Version=v2.2”为目标的项目中,但该包不包含任何与该框架兼容的程序集引用。如需更多信息,请联系包作者。
  • 找到了solution 包安装错误...
【解决方案3】:

在 Google 上进行了大量搜索后,我终于找到了解决方案 here

基本上我用StartActivity(intent);

【讨论】:

    猜你喜欢
    • 2011-08-03
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多