0%

第13讲-存储优化<中>-如何优化数据存储

Serializable 的原理

Serializable 的原理是通过 ObjectInputStream 和 ObjectOutputStream 来实现的,通过 Android 6.0 的源码可以看到 ObjectOutPutStream 的部分源码实现:

1
2
3
4
5
private void writeFieldValues(Object obj, ObjectStreamClass classDesc)  {
for (ObjectStreamField fieldDesc : classDesc.fields()) {
...
Field field = classDesc.checkAndGetReflectionField(fieldDesc);
...

整个序列化过程使用了大量反射(比如说获取整个类的所有属性,反射意味着效率低)和临时变量(临时变量意味着GC),并且,在序列化对象时,不仅会序列化当前对象本身,还需要地柜序列化对象引用的其他对象,可以参考别人的博客

Serializable 的进阶

Serializable 序列化支持使用自定义 writeObject和readObject,他会先反射判断是否存在我们自己实现的 序列化writeObject方法和反序列化readObject 方法。通过这两个方法,我们可以对某些字段做修改,也能实现序列化的加密功能。

还有,Serializable 的反序列默认是不会执行构造函数的

Parcelable 的永久存储

一般来说,我们使用 parcelable 只是会在内存中序列化操作,并不会存储到磁盘。其实,我们也可以存储到磁盘的:通过 Parcel.java 中的 marshall 接口获取byte 数组,然后存在文件中,从而实现 Parcelable 的永久存储。

1
2
3
4
5
6
7
8
// Returns the raw bytes of the parcel.
public final byte[] marshall() {
return nativeMarshall(mNativePtr);
}
// Set the bytes in data to be the raw bytes of this Parcel.
public final void unmarshall(byte[] data, int offset, int length) {
nativeUnmarshall(mNativePtr, data, offset, length);
}

不过,一般不推荐这样做,因为可能会有系统版本兼容性问题,因为我们无法保证所有的 Android 版本的 Parcel.cpp 实现完全一致。还有就是数据前后的兼容性,这里并没有类似 Serializable 里面有个 serialVersionUID 来保证版本一致性。

14-数据库优化

SQLite 默认支持多进程并发操作,它通过文件锁来控制多进程的并发,但是SQLite 的锁粒度并没有非常细,针对的是整个DB文件,简单来说,多进程可以同事获取 SHARED 锁来读取数据,但是只有一个进程可以获取 EXCLUSIVE 锁来写数据库

数据库使用注意:

  • 防止注入
  • 防止窃取
  • 小表无需维护索引,因为索引是需要一直维护的,有代价
  • 慎用 “select * “ 需要多少列,就取多少列
  • 定期删除无用数据
谢谢你的鼓励