存储优化和Protobuf
本文链接:https://blog.csdn.net/feather_wch/article/details/131649688
Android存储方式
1、Android存储方式
- SharePreference
- SQLite: 复杂的数据结构
- File -> protobuf,7z
- ContentProvider -> 和SQLite密切使用
- ContentResolver.call 可以实现AIDL效果,手机厂商做系统开发用的还蛮多。
- 网络 -> 序列化、反序列化 -> protobuf、xml、json
2、SharePreference的commit和apply是什么?
- apply没有返回值,commit返回boolean代表是否成功
- commit同步提交到硬盘;apply立即提交到内存,开启异步线程提交到硬盘,提交失败也不会通知
- commit同步;apply异步
- 主线程commit会出现anr
3、SharePreference支持多进程吗?
- 读支持
- 写不支持
- 总结:不支持
4、SQLite
- SQLiteStatement: 1000数据提高5s
- 事务
- 索引: 索引的原理
5、序列化
Protobuf
介绍
1、Protobuf相比于json、xml优点
- 使用简洁
- 体积小:大小只有xml 10%~33%(可变编码)
- 速度快:比xml快60~100倍
- Protobuf编译系统,编译成Java代码
- 兼容性好:更好线上线下兼容
- 缺点:可读性差
使用
- 根目录build.gradle文件中引入protobuf插件的classpath
buildscript {
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.9.3'
}
}
- app目录build.gradle中应用插件
plugins {
id 'com.google.protobuf'
}
- app目录build.gradle引入支持库
///引入支持库
implementation 'com.google.protobuf:protobuf-java:3.5.1'
- app目录build.gradle中配置compileOptions、packagingOptions、sourceSets
android {
// 省略
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/NOTICE' // will not include NOTICE file
exclude 'META-INF/LICENSE' // will not include LICENSE file
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/main/proto'//这里main下面存放.proto文件的目录名称不能为protobuf
}
}
}
}
- app目录build.gradle中配置protoc编译器
protobuf {
//配置protoc编译器
protoc {
artifact = 'com.google.protobuf:protoc:3.5.1'
}
//这里配置生成目录,编译后会在build的目录下生成对应的java文件
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.builtins {
java {}
}
}
}
}
- 创建目录:src/main/proto
- 放入编写的proto文件: package、java_package目录要和我们的一样
syntax = "proto3";
package com.test.myproto;//包名
option java_package = "com.test.myproto";
option java_outer_classname = "Person";
option csharp_namespace = "android";
message _Person{
string name = 1;
int32 id = 2;
string email = 3;
enum _PhoneType{
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message _PhoneNumber{
string number =1;
_PhoneType type = 2;
}
repeated _PhoneNumber phone = 4;//数组
}
- 编写测试代码 kotlin版本
// Bean -> protobuf
var personBuilder = Person._Person.newBuilder()
.setName("wch")
.setId(2)
.setEmail("xxx@qq.com")
var phoneNumberBuilder = Person._Person._PhoneNumber.newBuilder()
.setNumber("110")
.setType(Person._Person._PhoneType.HOME);
var person = personBuilder
.addPhone(phoneNumberBuilder) // 集合中添加数据
.build()
var byteArray = person.toByteArray()
println(Arrays.toString(byteArray))
// protobuf -> Bean
var newPerson = Person._Person.parseFrom(byteArray)
println(newPerson.toString())
原理
1、protobuf原理:变长编码
tag-length-value
- 采用小端字节序
7z压缩
- 7zip实战: JNI+NDK
- 用命令行方式让底层去处理