Android中的Parcelable詳解

Android中的Parcelable詳解

來自專欄全棧工程師

原文鏈接

github.com/shellhub/blo

這篇主要介紹如何在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

示例代碼

github.com/shellhub/and

推薦閱讀:

深入理解 Flutter 的編譯原理與優化
【原生AR開發必看】NVisionXR引擎教程(不斷更新中……)
跨平台APP對Cordova,APPCan,DCloud,APICloud四大平台的分析
Activity生命周期里的「隱秘」
Android 如何載入本地html

TAG:Android | 移動開發 | 谷歌Google |