基于 Android 的文件同步设计方案_android同步文件夹(3)

在产品的设计上,本次改动在设置里直接取消了用户关闭实时同步的选项。这是为了避免引入复杂的逻辑,造成用户费解。在这种情况下,帮用户做决策比给用户很多选择更好。

2.3 状态维护

第一种方案的问题之一是它的文件状态的维护。按照之前的分析,将文件的状态维护在服务器并非最理想的选择。因此,新的方案采用了将状态维护在本地的方案。新方案中,文件的状态被记录在数据库而不是文件中。这里有两点考虑:1).为避免一次性读取大量数据,减少内存占用;2).使用数据库可以进行结构化查询,方便灵活

对本地文件的状态,我设计了如下数据结构。新的同步方案中,我选用了 Room 作为数据库框架。因此,以下数据结构也大致对应数据库中的 Shcema,

/** 笔记上次同步状态 /
@Entity class NoteLastSyncState: Serializable {
@PrimaryKey(autoGenerate = true) var id: Long? = null
/
* 笔记的路径 /
var path: String? = null
/
* 文件相对路径,直接父路径,用来根据父路径找子路径 /
var parent: String? = null
/
* 如果文件时移动过来的话,记录从哪里移动过来的 /
var movedFrom: String? = null
/
* 服务器返回的上次修改的时间,如果有的话,用来判断远程是否修改过 /
var serverLastModifiedTime: Date? = null
/
* 上次同步时的 Md5 值,用来判断上次同步完成之后是否又被改动过 /
var lastSyncMd5: String? = null
/
* 备注信息,冗余字段,用 json 存储 /
var remark: String? = null
/
* 上次同步的时间 */
var lastSyncTime: Date? = null
}

这里的 path 字段是该文件相对于笔记根目录的路径。parent 是它的父目录相对于笔记根目录的路径。parent 的作用是用来根据父目录查找其所有的子文件/目录。比如下面的 SQL 就是基于前缀的匹配方式查询父目录的子文件/目录的状态,

@Query("SELECT * FROM NoteLastSyncState WHERE path LIKE :parent || ‘%’ ")
fun getUnderParent(parent: String): List

在实际编码之前应该先做技术方案。parent 等字段是在方案确定了基础之上,确定需要用到该字段,才将它们加入到数据结构中的。

这里的 movedFrom 用来记录该文件是从哪个位置移动过来的。在最初设计方案的时候,我本打算让移动行为走删除和新增的逻辑。这种思路虽然可行,但是性能会低。因为每个文件的删除和新增都要请求一次网络。当一个目录下存在很多子孙文件/目录的时候,请求的数量会非常多。因此,这里我使用 movedFrom 标记文件从何处移动而来。然后,在同步的时候,再根据该字段,调用服务器的移动接口,直接在服务器进行移动操作。这样一个请求即可完成同步。对于用户直接通过文件管理器移动目录或者文件的情况,由于不存在 movedFrom 标记,会走删除和新增的逻辑(被移动的位置删除,移动到的位置新增)。

这里的 serverLastModifiedTime 用来记录服务器返回的文件的上次修改时间。因为当我们请求一个目录的信息的时,可以获取到该目录下所有子文件的状态,其中就可能包含文件的上次修改时间。因此,每次同步完成之后,我们会记录该文件的上次修改时间。这样,下次同步的时候,通过对比服务器和本地数据库中的上次修改时间,我们就可以判断远程是否对文件做了修改,而无需使用文件的 md5. 这样就可以大幅提升同步的速率并降低流量的消耗。需要注意的是,这里用到的是服务器的修改时间,因为本地时间是不可靠的。

需要注意的是,我们不能假设服务器一定返回文件的上次修改时间字段。因此,它在新的同步方案中是作为判断逻辑的第一道防线。只有确保该字段一定存在的情况下才会使用它作为判断依据。代码如下所示,

/** Check is file changed remotely by last modified time. */
private fun isFileChangedRemotely(
syncState: NoteLastSyncState,
remoteFile: CloudResource
): Boolean = syncS

  • 14
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值