美文网首页
【Android性能优化面试题】为什么使用 Parcelable

【Android性能优化面试题】为什么使用 Parcelable

作者: 小城哇哇 | 来源:发表于2023-11-09 22:30 被阅读0次

    为什么使用 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。

    image.png

    对比

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

    最后

    有需要面试题的朋友可以关注一下哇哇,以上都可以分享!!!

    相关文章

      网友评论

          本文标题:【Android性能优化面试题】为什么使用 Parcelable

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