Android数据缓存框架 - 开始框架代码编写

我们知道,总共是有以下三个主要模块的

-   ORM
-   网络请求
-   数据缓存的核心逻辑

按理说ORM和网络请求更加基础,应该先讲,但是,我并不这么做。我要是讲ORM和网络请求,估计很多人就不想看了。众所周知,ORM和网络请求都有大量成熟的开源库来支持了。我本次要编写的框架的重点不是在这两块上,而是这两个模块的桥梁,简单的说,就是整合这两个模块的中间层。

框架我们打算采用Kotlin语言进行编写。

由于我们知道了数据缓存的流程,那么我们直接定义一个控制整体流程的接口。

```
package dora.cache.holder

import dora.db.builder.Condition

/**
* 控制缓存和加载数据的流程。
*/
interface CacheHolder<M> {
    
    /**
    * 该类型数据库orm框架的一些初始化操作在这里进行。
    */
    fun init()
    
    /**
    * 从数据库中加载数据到内存。
    */
    fun queryCache(condition: Condition) : M?
    
    /**
    * 查询缓存记录数量。
    */
    fun queryCacheSize(condition: Condition) : Long
    
    /**
    * 移除旧的数据库缓存。
    */
    fun removeOldCache(condition: Condition)
    
    /**
    * 将最新的数据缓存到数据库。
    */
    fun addNewCache(model: M)
}
```

M即我们要缓存的model数据,但它并不完全等同于api接口返回的数据根,后面我们会讲到ResultAdapter结果适配器,我们先认为api接口返回的json直接就是我们要整体缓存的数据。这里还出现了一个Condition类,它是我们定义的一个连接orm框架的桥梁,我们以后通过它来更换orm框架这一层。

```
package dora.db.builder

/**
 * 查询条件,它是一个和orm框架整合的协议。
 */
class Condition(
        // 条件语句,如 a > ? and a < ? , 或 a > 0
        val selection: String,
        // 条件参数,如 a > ? and a < ?中两个?的具体值0和100
                val selectionArgs: Array<String?>,
        // 同sql语句limit的用法
                val limit: String? = "",
        // 同sql语句order by的用法
                val orderBy: String? = "",
        // 同sql语句group by的用法
                val groupBy: String? = "",
        // 同sql语句having的用法
                val having: String? = "")
```

我们打算自己写一个orm框架,而如果框架使用者要使用别人的orm框架,则可以通过它来整合,这个我们以后再考虑。

我们自己实现一个CacheHolder。

```
package dora.cache.holder

import dora.db.table.OrmTable
import dora.db.builder.Condition
import dora.db.builder.WhereBuilder
import dora.db.dao.DaoFactory
import dora.db.dao.OrmDao

/**
 * 内置的CacheHolder,默认实现。
 */
class DoraCacheHolder<M, T : OrmTable>(var clazz: Class<out OrmTable>) : CacheHolder<M> {

    private lateinit var dao: OrmDao<T>

    override fun init() {
        // 创建指定类型的OrmDao
        dao = DaoFactory.getDao(clazz) as OrmDao<T>
    }

    override fun queryCache(condition: Condition): M? {
        return dao.selectOne(WhereBuilder.create(condition)) as M?
    }

    override fun removeOldCache(condition: Condition) {
        dao.delete(WhereBuilder.create(condition))
    }

    override fun addNewCache(model: M) {
        dao.insert(model as T)
    }

    override fun queryCacheSize(condition: Condition): Long {
        return dao.selectCount(WhereBuilder.create(condition))
    }
}
```

OrmDao的用法我们暂不细究,它就是用来操作sqlite数据库的。

由于api接口不一定给我们的json数据正好就是我们要缓存的model数据。我们需要定义一个指定数据要缓存的部分的接口Result。

```
package dora.cache.data.adapter

/**
 * 如果api接口返回的model并非直接为要缓存的model对象,即非[dora.db.table.OrmTable]的子类,则通过这个接口指定要
 * 缓存的数据。
 */
interface Result<M> {

    /**
     * 真实要缓存的model,返回api接口返回数据的一个属性。
     */
    fun getRealModel() : M?
}
```

比如api接口返回json

```
{
  "code": "000000",
  "message": "请求成功",
  "data": {
    "username": "dora123",
    "score": 0,
    "vip": 0,
    "token": "token:Android-20220721232231-E84E30B9390CDB64DB6DB2C9AB87846D"
  },
  "timestamp": 1658416951883
}
```

很明显,这些状态不是我们要缓存的数据,我们真正要缓存的数据是data字段的整体,我们getRealModel就返回model中的data属性作为真实要缓存的model。这样用的话,数据根就要实现Result接口。

我们网络模块那一层则通过ResultAdapter进行适配。

```
package dora.cache.data.adapter

import dora.http.DoraCallback

/**
 * 将实现[dora.cache.data.adapter.Result]的api接口返回的model数据适配成框架需要的[dora.http.DoraCallback]
 * 对象。
 */
class ResultAdapter<M, R : Result<M>>(val callback: DoraCallback<M>) : DoraCallback<R>() {

    /**
     * 适配[dora.http.DoraCallback]成功的回调。
     */
    override fun onSuccess(model: R) {
        model.getRealModel()?.let { callback.onSuccess(it) }
    }

    /**
     * 适配[dora.http.DoraCallback]失败的回调。
     */
    override fun onFailure(msg: String) {
        callback.onFailure(msg)
    }
}
```

网络模块的实现我们暂也不用了解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dora丶Android

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值