一起养成写作习惯!这是我参与「日新计划 4 月更文挑战」的第2天,点击查看活动详情。
序列化

将实例的状态转换为可以存储或传输的形式的过程。
Objecandroid是什么手机牌子tOutputStream
构造函数
public ObjectOutputStream(OutputStream out) throws IOException { verifySubclass(); bout = new BlockDataOutputStream(out);//用于写入文件的Stream handles = new HandleTable(10, (float) 3.00); subs = new ReplaceTable(10, (float) 3.00); enableOverride = false; writeStreamHeader(); //开始写入魔数和版本号 bout.setBlockDataMode(true); if (extendedDebugInfo) { debugInfoStack = new DebugTraceInfoStack(); } else { debugInfoStack = null; } }
write二进制Object方法
public final void writeObject(Object obj) throws IOException { if (enableOverride) { writeObjectOverride(obj); return; } try { writeObject0(obj, false); } catch (IOException ex) { if (depth == 0) { try { writeFatalException(ex); } catch (IOException ex2) { } } throw ex; } }
调用writeObject0方法
private void writeObject0(Object obj, boolean unshared) throws IOException { 。。。 //创建出来一个原始数据的描述信息的实例 desc = ObjectStreamClass.lookup(cl, true); 。。。 //根据类型信息将实例信息写入输出流 if (obj instanceof Class) { writeClass((Class) obj, unshared); } else if (obj instanceof ObjectStreamClass) { writeClassDesc((ObjectStreamClass) obj, unshared); // END Android-changed: Make Class and ObjectStreamClass replaceable. } else if (obj instanceof String) { writeString((String) obj, unshared); } else if (cl.isArray()) { writeArray(obj, desc, unshared); } else if (obj instanceof Enum) { writeEnum((Enum<?>) obj, desc, unshared); } else if (obj instanceof Serializable) { writeOrdinaryObject(obj, desc, unshared); } else { if (extendedDebugInfo) { throw new NotSerializableException( cl.getName() + "n" + debugInfoStack.toString()); } else { throw new NotSerializableException(cl.getName()); } } }
ObjectStreamClass的创建过程
static ObjectStreamClass lookup(Class<?> cl, boolean all) {
...
Reference<?> ref = Caches.localDescs.get(key);//读取缓存
Object entry = null;
if (ref != null) {
entry = ref.get();
}
EntryFuture future = null;
if (entry == null) {
EntryFuture newEntry = new EntryFuture();
Reference<?> newRef = new SoftReference<>(newEntry);
do {
if (ref != null) {
Caches.localDescs.remove(key, ref);
}
ref = Caches.localDescs.putIfAbsent(key, newRef);
if (ref != null) {
entry = ref.get();
}
} while (ref != null && entry == null);
if (entry == null) {
future = newEntry;
}
}
if (entry instanceof ObjectStreamClass) { // check common case first
return (ObjectStreamClass) entry;
}
if (entry instanceof EntryFuture) {
future = (EntryFuture) entry;
if (future.getOwner() == Thread.currentThread()) {
entry = null;
} else {
entry = future.get();
}
}
//没有缓存的情况
if (entry == null) {
try {
entry = new ObjectStreamClass(cl);
} catch (Throwable th) {
entry = th;
}
if (future.set(entry)) {
Caches.localDescs.put(key, new SoftReference<Object>(entry));
} else {
entry = future.get();
}
}
if (entry instanceof ObjectStreamClass) {
return (ObjectStreamClass) entry;
} else if (entry instanceof RuntimeException) {
throw (RuntimeException) entry;
} else if (entry instanceof Error) {
throw (Error) entry;
} else {
throw new InternalError("unexpected entry: " + entry);
}
}
进入ObjectStreamClass构造函数
private ObjectStreamClass(final Class<?> cl) { this.cl = cl; ... name = cl.getName();//反射获取 isProxy = Proxy.isProxyClass(cl); isEnum = Enum.class.isAssignableFrom(cl); serializable = Serializable.class.isAssignableFrom(cl); externalizable = Externalizable.class.isAssignableFrom(cl); Class<?> superCl = cl.getSuperclass(); superDesc = (superCl != null) ? lookup(superCl, false) : null; ... suid = getDeclaredSUID(cl); fields = getSerialFields(cl); computeFieldOffsets(); initialized = true; }
读取属性中使用反射
private static ObjectStreamField[] getDefaultSerialFields(Class<?> cl) {
Field[] clFields = cl.getDeclaredFields();
ArrayList<ObjectStreamField> list = new ArrayList<>();
int mask = Modifier.STATIC | Modifier.TRANSIENT;
for (int i = 0; i < clFields.length; i++) {
if ((clFields[i].getModifiers() & mask) == 0) {
list.add(new ObjectStreamField(clFields[i], false, true));
}
}
int size = list.size();
return (size == 0) ? NO_FIELDS :
list.toArray(new ObjectStreamField[size]);
}
Parcelablkotlin面试题e

Kotlin 有一个Parceliz二进制亡者列车e注解可以帮我们生成实现Parcelable之后需要写的代码
- 对kotlin怎么读象自行实现出入口方法,避免对类结构的反射
- 二进制流存储在连续内存中,占用空间更小
- 牺牲易用性(可以通过Parcelize弥补),换取极致的性能
Serializable
- 用反射获取类的结构和属性信息,过程中会产生中间信息
- 有缓存结构,在解析相同类型的情况下,能复用缓存
- 性能在二进制转换器可接受的范围内,易用性比较好
Intent传值场景
进入Pjava模拟器arcel.java类中的writeSerializable
Serializable是先通过ObjectOutp二进制转化为十进制utStream,把对象转成ByteArray,再通过writeByteArray写入Parcel
public final void writeSerializable(@Nullable Serializable s) { if (s == null) { writeString(null); return; } String name = s.getClass().getName(); writeString(name); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(s); oos.close(); writeByteArray(baos.toByteArray()); } catch (IOException ioe) { throw new RuntimeException("Parcelable encountered " + "IOException writing serializable object (name = " + name + ")", ioe); } }
Parcelable 调用对象内部实现的writeToParcel方法中的逻辑,通过一些write方法直接写入Parcel
public static void writeToParcel(@Nullable CharSequence cs, @NonNull Parcel p, int parcelableFlags) { if (cs instanceof Spanned) { p.writeInt(0); p.writeString8(cs.toString()); Spanned sp = (Spanned) cs; Object[] os = sp.getSpans(0, cs.length(), Object.class); for (int i = 0; i < os.length; i++) { Object o = os[i]; Object prop = os[i]; if (prop instanceof CharacterStyle) { prop = ((CharacterStyle) prop).getUnderlying(); } if (prop instanceof ParcelableSpan) { final ParcelableSpan ps = (ParcelableSpan) prop; final int spanTypeId = ps.getSpanTypeIdInternal(); if (spanTypeId < FIRST_SPAN || spanTypeId > LAST_SPAN) { Log.e(TAG, "External class "" + ps.getClass().getSimpleName() + "" is attempting to use the frameworks-only ParcelableSpan" + " interface"); } else { p.writeInt(spanTypeId); ps.writeToParcelInternal(p, parcelableFlags); writeWhere(p, sp, o); } } } p.writeInt(0); } else { p.writeInt(1); if (cs != null) { p.writeString8(cs.toString()); } else { p.writeString8(null); } } }
由于ObjectSt二进制计算器reamClass存在缓存机制,在一次序列化过程中,如果涉及大量相同类的不同实例化,Serializable的性能会存在优势。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)