【Android性能优化面试题】为什么使用 Parcelable, 好处是什么?

为什么使用 Parcelable, 好处是什么?

这道题想考察什么?

JDK本身提供了Serializable序列化接口,为什么Android还要设计Parcelable?Parcelable相对于Serializable的区别是什么?它的实现原理又是什么?

考察的知识点

序列化与反序列化

考生如何回答

什么是序列化?

首先我们要了解什么是序列化?序列化是将对象的状态信息转换为可以存储或传输的形式的过程,序列化最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性。

就相当于我们现在要把埃菲尔铁塔完全一摸一样的搬到北京,实现这个过程就是序列化的过程。我们需要给埃菲尔铁塔的每个部件都打上标记,这个钢筋部件原来在哪个位置,搬到北京后仍然要在对应的位置。这就是将埃菲尔铁塔序列化了之后传输(运输)到北京。而反序列化自然就是利用运到北京的部件根据标记信息还原的过程。

Serializable的原理

那么JDK当中实现的Serializable序列化接口是如何将一个对象进行序列化的?

static class SerializableTest implements Serializable {
        int i;
        long j;

        public SerializableTest(int i, int j) {
            this.i = i;
            this.j = j;
        }

        @Override
        public String toString() {
            return "SerializableTest{" +
                    "i=" + i +
                    ", j=" + j +
                    '}';
        }
}


@Test
public void testSerialible() throws IOException, ClassNotFoundException {
        SerializableTest serializableTest = new SerializableTest(1, 2);
    	//序列化
        ObjectOutputStream os = new ObjectOutputStream(
            new FileOutputStream("SerializableTest"));
        os.writeObject(serializableTest);
        os.close();

    	//反序列化
        ObjectInputStream is = new ObjectInputStream(new FileInputStream("SerializableTest"));
        SerializableTest serializableTest1 = (SerializableTest) is.readObject();
        System.out.println(serializableTest1);
}

对于JVM来说,要进行持久化的类必须要有一个标记,只有持有这个标记JVM才允许类创建的对象可以通过其IO系统转换为字节数据,从而实现持久化,而这个标记就是Serializable接口。而在反序列化的过程中则需要使用serialVersionUID来确定由哪个类来加载这个对象,如果我们在序列化中没有显示地声明serialVersionUID,则序列化运行时将会根据该类的各个方面计算该类默认的serialVersionUID值。 但是,Java官方强烈建议所有要序列化的类都显示地声明serialVersionUID字段,因为如果高度依赖于JVM默认生成serialVersionUID,可能会导致其与编译器的实现细节耦合,为了保证跨不同Java编译器实现的serialVersionUID值的一致,实现Serializable接口的必须显示地声明serialVersionUID字段。

总之实现了Serializable接口就相当于给类打上了一个标记,JVM就能够对类对象信息按照(Serializable)规则记录,而反序列化就按照规则解析即可。

Parcelable的原理
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();
      } 

我们通过Serializable的使用可以发现,Serializable需要使用IO对序列化数据直接写入到文件当中。而Parcelable是android特有的序列化方式,我们在开发中可能并不需要将数据保存到文件当中,只在内存中进行传输使用,此时使用Parcelable将更为高效,因为Parcelable依赖于Parcel,Parcel的意思是包装,实现原理是在内存中建立一块共享数据块,序列化和反序列化均是操作这一块的数据,而不像Serializable需要使用IO。

在这里插入图片描述

对比
  • Serializable是java序列化的方式,存取的过程有频繁的IO,性能较差,但是实现简单。
  • Parcelable是android序列化的方式,采用共享内存的方式实现用户空间和内核空间的交换,性能很好,但是实现方式比较复杂。
  • Serializable可以持久化存储,Parcelable是存储在内存中的,不能持久化存储。

最后

我整理了一套Android面试题合集,除了以上面试题,还包含【Java 基础、集合、多线程、虚拟机、反射、泛型、并发编程、Android四大组件、异步任务和消息机制、UI绘制、性能调优、SDN、第三方框架、设计模式、Kotlin、计算机网络、系统启动流程、Dart、Flutter、算法和数据结构、NDK、H.264、H.265.音频编解码、FFmpeg、OpenMax、OpenCV、OpenGL ES
在这里插入图片描述

有需要的朋友可以扫描下方二维码,免费领取全部面试题+答案解析!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值