只是补充一下@uj- 所说的,需要 Parcelling/Serializing,因为 @uj- 表示它将跨 JVM 发送,因此需要将它们转换为某种格式,以便对方能够理解。
让我举个例子来解释为什么需要序列化/打包,
您正在将数据从用“C++”编写的应用程序发送到用 java 编写的应用程序,因此以下是类,
在 C++ 中,
class Android {
public: int dataToSend; //for example purpose making field public and omitting setter/getters
}
在 Java 中,
class Android{
public int dataToSend;
}
假设C++代码生成动态库(使用标准C++编译器编译生成然后链接),Java代码生成jar(使用javac编译)。
当 C++ 应用程序向 java 应用程序发送数据(Android 类的对象)时,它在 C++ 中的编译和链接方式与在 java 中的编译方式完全不同,因此 java 会想知道这个 C++ 有什么申请已发送给我。
因此,为了摆脱这些问题,需要序列化/打包,这将确保两个应用程序都知道数据在通过网络传输时是如何转换的(如果是 android,它是如何传输到另一个活动的,可能在相同或不同的应用程序)。
是的,当我们开始比较序列化和 Parcelling 时,Parcelling 占上风,因为我们将指定在发送数据时必须转换数据的方式,否则在序列化的情况下,对象将使用反射和反思总是需要时间的。因此,与序列化相比,Parcelling 更快。
第二个问题,
如果我们考虑上面的例子本身,那么我们可以说 String 和 int 是原始类型(其中没有用户定义的字段),因此 android 将能够处理将要发送的数据的编组和解组。
当我们继续深入挖掘时,我尝试检查代码,最终得到了 @uj- 所说的本机代码。
部分摘自android源代码:
在写包裹时:
parcel.writeInt(BUNDLE_MAGIC);
int startPos = parcel.dataPosition();
parcel.writeArrayMapInternal(mMap);
int endPos = parcel.dataPosition();
parcel.setDataPosition(lengthPos);
int length = endPos - startPos;
parcel.writeInt(length);
parcel.setDataPosition(endPos);
在阅读包裹时,
int magic = parcel.readInt();
if (magic != BUNDLE_MAGIC) {
//noinspection ThrowableInstanceNeverThrown
throw new IllegalStateException("Bad magic number for Bundle: 0x"
+ Integer.toHexString(magic));
}
int offset = parcel.dataPosition();
parcel.setDataPosition(offset + length);
Parcel p = Parcel.obtain();
p.setDataPosition(0);
p.appendFrom(parcel, offset, length);
p.setDataPosition(0);
mParcelledData = p;
设置一个幻数,它将在写入时识别包裹的开始,在我们读取包裹时使用相同的数字。
希望我回答了你的问题。