美文网首页Android Developer程序员
Android中的Parcelable详解

Android中的Parcelable详解

作者: duyuanchao | 来源:发表于2018-09-12 10:03 被阅读6次
android-parcelable-2-1024x576.jpg

原文链接

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) {

效率对比

1 d4iacvhmfirbgr4c0yqcvw

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

相关文章

网友评论

    本文标题:Android中的Parcelable详解

    本文链接:https://www.haomeiwen.com/subject/fqbmgftx.html