如有不正確的地方,請幫我指正。
簡介
要在同一程序的不同組件之間(如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