Android基础系列(5)了解Parcelable

1,514 阅读2分钟

前言

Parcelable是Android为我们提供的序列化的接口。
下面我们从几个问题出发去深入了解它。

  1. parcelable的作用?
  2. parcelable如何序列化?
  3. parcelable如何反序列化?
  4. 什么时候使用parcelable比较好?

1 parcelable的作用

将对象变成字节序列,便于存储,网络传输对象,进程间传递对象。

2 parcelable序列化与反序列化

实体类实现Parcelable后,Android Studio会提示自动补全必要的方法。

public class User implements Parcelable {

    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // TODO 读写顺序必须一致,否则会出现数据紊乱。

    // 从Parcel对象里读出数据,赋值给成员变量
    protected User(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    // 序列化
    // 把属性写入Parcel对象中
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    @Override
    public int describeContents() {
        return 0;
    } // 一般为0,只有一些特殊的类返回1

    // 反序列化
    // 必须实现 CREATOR 名称不可变
    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];
        }
    };
}

3 进程间传递对象

大致了解了Parcelable的序列化后,我们以进程间传递对象来实际应用一下。

通过intent传递对象

// User对象延续使用上面那个
User user = new User("张三", 78);
Intent intent = new Intent(getActivity(), TestActivity.class);
intent.putExtra("user", user);
startActivity(intent);

创建TestActivity,独立进程,接收对象并打印

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        User user = getIntent().getParcelableExtra("user");
        Log.i("接收对象:", user.toString());
    }
}
// TestActivity放到单独的进程中
<activity
    android:name=".TestActivity"
    android:process=":test"/>

结果

屏幕快照 2021-03-25 上午11.01.18.png

4 什么时候使用Parcelable比较好

相比与Serializable,Parcelable经过Google工程师的定制处理后,IO效率明显高得多。所以博主的建议是,内存间的对象传递最好用Parcelable,用Serializable也可以。
但是,如果做持久化存储或网络间的传输,用Serializable,它是通用的序列化机制。
下面是Google官方的说法。

Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.

Parcel不是通用的序列化机制。此类(以及Parcelable用于将任意对象放入Parcel的相应 API)被设计为高性能IPC传输。因此,将任何Parcel数据放置到持久性存储中是不合适的:对Parcel中任何数据的基础实现进行更改会导致较旧的数据不可读。