(每次学习一点xamarin就做个学习笔记和视频来加深记忆巩固知识)
如有不正确的地方,请帮我指正。
简介
要在同一程序的不同组件之间(如Activity与Activity之间)传递对象或者要在两个不同进程之间传递对象,就可以使用Parcel和IParcelable来实现。
也可用ISerializable,但ISerializable在序列化对象时会产生大量临时变量,效率不高。
还可以用Json字符串来传递对象。
查看Intent类,可以看到要传递一个对象或多个对象是使用下面的方法
查看IParcelable接口
查看IParcelableCreator接口
举个例子,首先定义个Book类,实现IParcelable接口
如下所示
如有不正确的地方,请帮我指正。
简介
要在同一程序的不同组件之间(如Activity与Activity之间)传递对象或者要在两个不同进程之间传递对象,就可以使用Parcel和IParcelable来实现。
也可用ISerializable,但ISerializable在序列化对象时会产生大量临时变量,效率不高。
还可以用Json字符串来传递对象。
主要用到下面的类和接口
Parcel类 |
可把数据序列化以方便传输,IPC(跨进程)传输数据用到了此类。 |
IParcelable接口 |
用来定义(把数据写到Parcel中的)方法。(即规定打包方法) |
IParcelableCreator接口 |
用来定义(从Parcel中解析出数据的)方法。(即规定解包方法) |
具体打包和解包方法让我们自己去实现,系统到时自动调用。
使用查看Intent类,可以看到要传递一个对象或多个对象是使用下面的方法
public class Intent
{
//..........................
public virtual Intent PutExtra(string name, IParcelable value);
public virtual Intent PutExtra(string name, IParcelable[] value);
//..........................
}
也就是要求必须是实现了IParcelable接口的对象才可传递。
查看IParcelable接口
namespace Android.OS
{
public interface IParcelable : IJavaObject, IDisposable
{
void WriteToParcel(Parcel dest, [GeneratedEnum] ParcelableWriteFlags flags);
int DescribeContents();
}
}
从上面的代码可看出,这个接口定义了两个要实现的方法,WriteToParcel()是用来把数据打包到Parcel对象中,需要我们来实现具体要把对象中的哪些数据以什么顺序打包进去。DescribeContents()是在系统内部进行安全保护所使用的,返回0即可,不用管它。
查看IParcelableCreator接口
namespace Android.OS
{
public interface IParcelableCreator : IJavaObject, IDisposable
{
Java.Lang.Object CreateFromParcel(Parcel source);
Java.Lang.Object[] NewArray(int size);
}
}
从上面的代码可看出,这个接口定义了两个要实现的方法,CreateFromParcel(Parcel source)方法用于将parcel对象的数据解析为指定的对象。NewArray不用管,直接返回指定对象的数组就行。
举个例子,首先定义个Book类,实现IParcelable接口
public class Book :Java.Lang.Object, IParcelable
{
public int BookId{ get; set; }
public string BookName { get; set; }
public double BookPrice { get; set; }
public Book()
{
}
//自定义个解析数据的方法(解析顺序和打包顺序一定要一致)
private Book(Parcel parcel)
{
BookId = parcel.ReadInt();
BookName = parcel.ReadString();
BookPrice = parcel.ReadDouble();
}
//打包数据到Parcel类的对象dest中 (解析顺序和打包顺序一定要一致)
public void WriteToParcel(Parcel dest, [GeneratedEnum] ParcelableWriteFlags flags)
{
dest.WriteInt(BookId);
dest.WriteString(BookName);
dest.WriteDouble(BookPrice);
}
public int DescribeContents()
{
return 0; //这个值是在系统内部进行安全保护所使用的,就填0即可
}
private static readonly BookParcelableCreator _creator = new BookParcelableCreator();
[ExportField("CREATOR")]//必须使用CREATOR这个固定的名称
public static BookParcelableCreator GetCreator()
{
return _creator;
}
}
然后还是在Book类中,定义个BookParcelableCreator类,实现IParcelableCreator接口
public class BookParcelableCreator : Java.Lang.Object, IParcelableCreator
{
public Java.Lang.Object CreateFromParcel(Parcel source)
{
return new Book(source);
}
public Java.Lang.Object[] NewArray(int size)
{
return new Java.Lang.Object[size];
}
}
然后就可以使用了,在MainActivity中发送对象到另一个Activity
public class MainActivity : AppCompatActivity
{
//...........................省略其它代码
private void SendBookToActivity()
{
Book book = new Book();
book.BookId = 1;
book.BookName = "C#高级编程";
book.BookPrice = 68.8;
Intent intent = new Intent(this, typeof(SecondActivity));
intent.PutExtra("s", book);
this.StartActivity(intent);
}
}
然后在SecondActivity中接收Book对象
public class SecondActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Second);
var book = Intent.GetParcelableExtra("s") as Book;
if (book != null)
Toast.MakeText(this, book.BookName, ToastLength.Long).Show();
}
}
可以把上面的BookParcelableCreator类的功能提取出来做个通用的,这样其它实体类就不用再写像BookParcelableCreator类这样的代码了。
如下所示
public sealed class MyParcelableCreator<T> : Java.Lang.Object, IParcelableCreator
where T:Java.Lang.Object,new ()
{
private readonly Func<Parcel, T> _createMethod;
public MyParcelableCreator(Func<Parcel, T> createMethod)
{
_createMethod = createMethod;
}
public Java.Lang.Object CreateFromParcel(Parcel source)
{
return _createMethod(source);
}
public Java.Lang.Object[] NewArray(int size)
{
return new T[size];
}
}
然后在Book类中这样使用
private static readonly MyParcelableCreator<Book> _creator = new MyParcelableCreator<Book>(parcel => new Book(parcel));
//解包数据
private Book(Parcel parcel)
{
BookId = parcel.ReadInt();
BookName = parcel.ReadString();
BookPrice = parcel.ReadDouble();
}
[ExportField("CREATOR")]
public static MyParcelableCreator<Book> GetCreator()
{
return _creator;
}
代码和视频在我上传的CSDN资源中
http://download.csdn.net/download/junshangshui/10121790