Android中的Parcelable詳解
來自專欄全棧工程師
原文鏈接
https://github.com/shellhub/blog/issues/27
這篇主要介紹如何在Android中實現Parcelable
Bundle對象傳遞數據
我們都知道,可以使用Bundle對象在Andriod各大組建之間傳遞數據,使用Bundle.putXXX(KEY, VALUE)
可以存放一些基本數據類型以及封裝類型,以下是Bundle對象可以存儲的數據類型
- primitives(基本數據類型)
- String
- Serializable
- Parcelable
存儲的時候使用鍵值的方式進行存儲並傳遞
如果我們需要使用Bundle傳遞對象,我們可以
implements Serializable
,或者implements Parcelable
實現Serializable介面
這種方式非常簡單,我們直接實現Serializable
介面就行,這個介面是一個空的介面,所以我們不需要做任何操作,如果有必要我們可以定義一個serialVersionUID
public interface Serializable {}
我們常見的File
類就實現了這個介面
public class File implements Serializable, Comparable<File>{ ...}
實現Parcelable介面
這個相比與 Serializable稍微複雜一點,不過是 Google
推薦的方式,我們來看看官方給的一個例子
public class MyParcelable implements Parcelable { private int mData; public int describeContents() { return 0; } public void writeToParcel(Parcel out, int flags) { out.writeInt(mData); } public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() { public MyParcelable createFromParcel(Parcel in) { return new MyParcelable(in); } public MyParcelable[] newArray(int size) { return new MyParcelable[size]; } }; private MyParcelable(Parcel in) { mData = in.readInt(); }}
這個例子中的對象只包含了一個屬性mData
,我們在看一個例子
public class User implements Parcelable { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } protected User(Parcel in) { name = in.readString(); age = in.readInt(); } public static final Creator<User> CREATOR = new Creator<User>() { @Override public User createFromParcel(Parcel in) { return new User(in); } @Override public User[] newArray(int size) { return new User[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "name=" + name + + ", age=" + age + }; }}
傳遞Parcelable對象並解析
傳遞
User user = new User("shellhub", 23);Intent intent = new Intent(this, SecondActivity.class);intent.putExtra(KEY, user);startActivity(intent);
解析
User user = getIntent().getExtras().getParcelable(KEY);
因為方法實現了泛型,所以不需要類型轉換
public <T extends Parcelable> T getParcelable(@Nullable String key) {
Serializable 和 Parcelable之間的區別
- Parcelable比 Serializable快
- Parcelable需要花更多的時間寫更多的代碼
- Serializable實現更加簡單
- Serializable介面會創建大量臨時對象並導致相當多的垃圾回收
- Parcelable數組可以通過android中的Intent傳遞
public @NonNull Intent putExtra(String name, Parcelable[] value) {
效率對比
Q&A
對象中定義的CREATOR
可以改為其他名字么? * 不可以,如果定義為其他名字會報以下錯誤
Caused by: android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR on class com.github.shellhub.parcelable.User
示例代碼
https://github.com/shellhub/android-samples/tree/master/Parcelable
推薦閱讀:
※深入理解 Flutter 的編譯原理與優化
※【原生AR開發必看】NVisionXR引擎教程(不斷更新中……)
※跨平台APP對Cordova,APPCan,DCloud,APICloud四大平台的分析
※Activity生命周期里的「隱秘」
※Android 如何載入本地html