diff --git a/blogs/Android/Serializable 与 Parceable.md b/blogs/Android/Serializable 与 Parceable.md new file mode 100644 index 0000000..ad672a2 --- /dev/null +++ b/blogs/Android/Serializable 与 Parceable.md @@ -0,0 +1,8 @@ +--- +Serializable 与 Pracelable +--- + +#### 目录 + +1. 思维导图 +2. \ No newline at end of file diff --git a/blogs/Android/存储优化.md b/blogs/Android/存储优化.md index d56eb27..048146a 100644 --- a/blogs/Android/存储优化.md +++ b/blogs/Android/存储优化.md @@ -19,6 +19,8 @@ #### 思维导图 +![](https://i.loli.net/2019/01/15/5c3dbef17beaf.png) + #### Android 的存储基础 ##### Android 分区 @@ -113,4 +115,18 @@ Android 系统可以通过 df 命令来查看分区情况,常见的分区如 虽然 ContentProvider 为应用程序之间的数据共享提供了很好的安全机制,但是如果 ContentProvider 是 exported,当支持执行 SQL 语句时就需要注意 SQL 注入的问题。另外如果我们传入的参数是一个文件路径,然后返回文件的内容,这个时候也要校验合法性,不然整个应用的私有数据就可能被别人拿到,在 intent 传递参数的时候可能也会有这个问题。 - 总的来说,ContentProvider 这套方案实现相对比较笨重,适合传输大的数据。 \ No newline at end of file + 总的来说,ContentProvider 这套方案实现相对比较笨重,适合传输大的数据。 + +- SQLite + + 总的来说,通过引入 ORM,可以大大的提升我们的开发效率;通过 WAL 模式和连接池,可以提高 SQLite 的并发性能;通过正确的建立索引,可以提升 SQLite 的查询速度;通过调整默认页大小和缓存大小,可以提升 SQLite 的整体性能。 + + 详见:[SQLite](https://github.com/Omooo/Android-Notes/blob/master/blogs/SQLite.md) + +#### 参考 + +[存储优化(上):常见的数据存储方法有哪些?](https://time.geekbang.org/column/article/76677) + +[存储优化(中):如何优化数据存储?](https://time.geekbang.org/column/article/76985) + +[存储优化(下):数据库SQLite的使用和优化](https://time.geekbang.org/column/article/77546) \ No newline at end of file diff --git a/blogs/SQLite.md b/blogs/SQLite.md index 1371ac3..b505a07 100644 --- a/blogs/SQLite.md +++ b/blogs/SQLite.md @@ -19,11 +19,12 @@ Android 数据持久化之 SQLite - 优化建议 - 事务 - 建立索引 + - 页大小和缓存大小 3. 参考 #### 思维导图 -![](https://raw.githubusercontent.com/Omooo/Android-Notes/master/images/SQLite.png) +![](https://i.loli.net/2019/01/15/5c3dbf22234b0.png) #### 基本使用 @@ -89,11 +90,30 @@ SQLite 默认是支持多进程并发操作的,它通过文件锁来控制多 为了进一步提高并发性能,我们还可以打开 WAL(Write-Ahead Logging)模式。WAL 模式会将修改的数据单独写到一个 WAL 文件中,同时也会引入 WAL 日志文件锁。通过 WAL 模式读和写可以完全的并发执行,不会相互阻塞。 +```java +db.enableWriteAheadLogging(); //返回 false / true ``` -PRAGMA schema.journal_mode = WAL + +如果开启了 WAL 模式,开启事务要使用 benginTransactionNonExclusive(),注意捕获异常,源码如下: + +```java + /** + *
+     *   db.beginTransactionNonExclusive();
+     *   try {
+     *     ...
+     *     db.setTransactionSuccessful();
+     *   } finally {
+     *     db.endTransaction();
+     *   }
+     * 
+ */ + public void beginTransactionNonExclusive() { + beginTransaction(null /* transactionStatusCallback */, false); + } ``` -**但是需要注意的是,写之间仍然不能并发。**如果出现多个写并发的情况,依然有可能出现 SQLiteDatabaseLockedException,这个时候可以让应用捕获这个异常,然后等待一段时间后重试。 +但是需要注意的是,**写之间仍然不能并发。**如果出现多个写并发的情况,依然有可能出现 SQLiteDatabaseLockedException,这个时候可以让应用捕获这个异常,然后等待一段时间后重试。 总的来说,通过连接池与 WAL 模式,可以很大程度上增加 SQLite 的读写并发,大大减少由于并发导致的等待耗时,建议在应用中尝试开启。 @@ -190,7 +210,13 @@ SQLite 默认会为每个插入、更新操作创建一个事务,并且在每 数据库就像一个小文件系统,事实上它内部也有页和缓存的概念。 -对于 SQLite 的 DB 文件来说,页是最小的存储单位。跟文件系统的页缓存一样,SQLite 会将读过的页缓存起来,用来加快下一次读取速度,页大小默认是 1024 Byte,缓存大小默认是 1000 页。建数据库的时候,就提前选择 4KB 作为默认的 page size 以获得更好的性能。 +对于 SQLite 的 DB 文件来说,页是最小的存储单位。跟文件系统的页缓存一样,SQLite 会将读过的页缓存起来,用来加快下一次读取速度,页大小默认是 1024 Byte,缓存大小默认是 1000 页。如果使用 4KB 的 pageSize 性能能提升 5%~10% 左右,所以在建数据库的时候,就提前选择 4KB 作为默认的 page size 以获得更好的性能。 + +```java +db.setPageSize(1024 * 4); +``` + + ##### 其他优化 diff --git a/images/SQLite.png b/images/Android/SQLite.png similarity index 100% rename from images/SQLite.png rename to images/Android/SQLite.png diff --git a/images/Android/存储优化.png b/images/Android/存储优化.png new file mode 100644 index 0000000..1ff4ffb Binary files /dev/null and b/images/Android/存储优化.png differ