关于android:Android-Activity-传递Parcelable对象

后面咱们晓得了启动activity的时候能够传递一些参数。Activity的跳转时能够传递Parcelable对象。

Parcelable对象和Serializable不一样。实现了Parcelable接口的类并不会被零碎序列化。
接下来咱们用一个例子看看如何应用这一接口。

应用例子

先筹备数据,而后传送Parcelable对象。

数据筹备

先设计一个类实现Parcelable接口。后面咱们应用Serializable的时候,类只有实现Serializable接口即可,不须要额定的操作。但用Parcelable接口会须要开发者多做一些工作。

Parcelable接口在android.os包里,与Serializable不同。咱们必须明确意识这一点。
官网给出的一个应用例子。

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();
      }
}

能够看到,强制应用了一个Parcelable.Creator对象。外面的办法咱们临时不论也不批改。
重点关注公有结构器MyParcelable(Parcel inwriteToParcel办法。

官网例子中,公有结构器接管一个Parcel对象,而后从中读出一个int。而writeToParcel办法中,把mData写入Parcel对象中。
这写入和读出操作就是咱们开发者须要特地关怀的中央。

之前应用intent.putExtra办法的时候会传入一个String类型的key(键),用于标示传入的数据。
但在官网的例子中,咱们只看到了一个int。而writeInt办法也没有指定key。零碎如何辨别出各个参数呢?

咱们自定义一个类DataParcel,实现Parcelable接口。as主动在外面生成了CREATOR


import android.os.Parcel;
import android.os.Parcelable;

public class DataParcel implements Parcelable {
    private int number;
    private String str1;
    private String str2;
    private String noSave = "[不传送的字符串]";
    
    // getter setter ...

    public String info() {
        return "number: "+number+", str1: "+str1+", str2: "+str2+", noSave: "+noSave;
    }

    protected DataParcel(Parcel in) {
        number = in.readInt();
        str1 = in.readString();
        str2 = in.readString();
    }

    public DataParcel(int number, String str1, String str2, String noSave) {
        this.number = number;
        this.str1 = str1;
        this.str2 = str2;
        this.noSave = noSave;
    }

    public static final Creator<DataParcel> CREATOR = new Creator<DataParcel>() {
        @Override
        public DataParcel createFromParcel(Parcel in) {
            return new DataParcel(in);
        }

        @Override
        public DataParcel[] newArray(int size) {
            return new DataParcel[size];
        }

    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(number);
        dest.writeString(str1);
        dest.writeString(str2);
    }
}

能够看到咱们有1个int和3个String。公开结构器须要传入这4个属性。

writeToParcel办法中,按程序写入了int和2个String。公有结构器中,按程序读出了int和2个String。

noSave并没有被写入和读出。拿来做比照。info()办法是拿来打印信息的。

传送Parcelable对象

当初咱们的类曾经设计好了,传送对象试试。

把DataParcel对象交给intent。

DataParcel dataParcel = new DataParcel(100, "s1", "s2", "扭转这个字符串看看是否被传递");
intent.putExtra(SendParamsDemo.K_PARCEL, dataParcel);

被关上的Activity接管传入的对象。

DataParcel dataParcel = intent.getParcelableExtra(K_PARCEL);

log中打印登程送和传入的对象信息。

D/rustAppMainActivity: goSendParamsDemo: parcel obj: com.rustfisher.tutorial2020.act.DataParcel@d8ce985
D/rustAppMainActivity: goSendParamsDemo: parcel obj: number: 100, str1: s1, str2: s2, noSave: 扭转这个字符串看看是否被传递

D/rustAppSendParamsDemo: gotInput: parcel obj: com.rustfisher.tutorial2020.act.DataParcel@d90a3a6
D/rustAppSendParamsDemo: gotInput: number: 100, str1: s1, str2: s2, noSave: [不传送的字符串]

从log中咱们能够看出,发送的对象和接管到的对象并不是同一个对象。但咱们指定的那3个属性是雷同的。

总结

至此,咱们理解了如何应用Parcelable这个接口。
ParcelParcelable是Android IPC中应用到的容器和工具。大家能够理解一下Binder机制

个别认为,一般状况下Parcelable性能上会优于Serializable
Serializable波及到序列化,零碎会通过反射的办法来获取信息。相对而言比拟耗资源。
Parcel并不波及序列化机制。它是为了高性能IPC传输设计的。因而,Parcel并不适宜用来永久化存储数据。

理论工作中,咱们能够依据业务须要,综合开发工夫老本和利用性能要求,来抉择应用Parcelable或者Serializable

  • 示例代码
  • Android Activity 传递Parcelable对象

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理