Android Room 将预打包的数据库存储在缓存中是不是正常?

Posted

技术标签:

【中文标题】Android Room 将预打包的数据库存储在缓存中是不是正常?【英文标题】:Is it normal for Android Room to be storing the prepackaged database in cache?Android Room 将预打包的数据库存储在缓存中是否正常? 【发布时间】:2021-12-17 22:04:30 【问题描述】:

我目前正在创建一个使用 预打包 数据库的 android 应用程序。该数据库最初大小约为 40MB,存储在 assets/databases 文件夹中。

问题 当我查看我的应用程序正在使用多少空间时,“应用程序信息”页面显示以下内容:

应用程序大小:~25mb 用户数据:~3mb 缓存:~45mb

我认为 ROOM 造成这种情况的原因如下:

    我没有在我的应用程序中缓存任何内容(使用设备文件资源管理器仔细检查)。 当我从 SQLiteOpenHelper 迁移到 Room 时,开始出现此问题 数据库的大小比 App Size 大很多,但它与 Cache 大小差不多,所以无论存储为 Cache 必须与数据库相关。 每当我从我的实体中添加/删除索引时,缓存大小都会发生变化。 当我清除缓存并打开应用程序时,缓存 大小恢复到 ~45mb。

Android ROOM 将预打包的数据库存储为 Cache 是否正常?任何帮助将不胜感激,如果您需要更多信息,请告诉我。 p>

谢谢

编辑(附加信息) 这是我在设备文件资源管理器中看到的

这就是我实现 Room 数据库的方式

@Database(entities = /* entities*/, version = 1, exportSchema = false)
public abstract class MyDatabase extends RoomDatabase 
    public abstract MyDao myDao();
    private static volatile Database INSTANCE;

    public static Database getDatabase(final Context context) 
        if (INSTANCE == null) 
            synchronized (MyDatabase.class) 
                if (INSTANCE == null) 
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                        MyDatabase.class, "database")
                        .createFromAsset("databases/database.db")
                        .build();
                
            
        

        return INSTANCE;
    

【问题讨论】:

【参考方案1】:

我相信您遇到的情况可能是由于:

    您使用inMemoryDatabaseBuilder 或 由于 Room 默认使用 WAL(预写日志),而您之前使用的是日志模式,您会感到困惑。

很可能是后者。

不同之处在于,在日志模式下,会保留对数据库所做更改的日志,因此当应用更改并需要新页面时,数据库会增长。而在 WAL 模式下,更改将应用​​于 -wal 文件,然后在点 (CHECKPOINT) 处将更改应用于数据库文件。因此,在发生 CHECKPOINT 之前,所有更改都存储在 -wal 文件中。

例如

-shm 文件是 WAL 文件的 WAL 文件

或许可以参考https://sqlite.org/wal.html

交换到一个 inMemory 数据库(没有其他更改,因此插入完全相同的数据)然后:-

通过设备文件资源管理器 通过应用检查(又名数据库检查器)

所以我怀疑 -wal 文件被视为缓存。

【讨论】:

嗨,迈克,感谢您的周到回复。我再次查看了设备文件资源管理器,看起来 wal 文件并没有占用太多空间。它主要由数据库文件占用。我用附加信息编辑了帖子以进行澄清。问题可能在于预填充的数据库文件本身,但可能不是因为当我使用 SQLiteOpenHelper 时一切正常。我会做更多的测试。再次感谢! @lexler uhhm createFromAsset 使用临时数据库(虽然不确定是否在内存中)。当然-wal文件的大小是动态的“准持久”。如果完全检查点(哎呀说答案中的提交(将更改)),则 wal 文件为空/不存在。然而,检查点默认情况下(自动检查点)大约是每 1000 页(4Mb),但它们是被动的,因此可能存在未完成的更改,这些未完成的更改留在 wal 文件中。 嗨,迈克,我尝试将房间数据库的日志模式更改为 TRUNCATE,但问题仍然存在,所以我认为 WAL 模式并不是造成这种情况的原因。当我对房间数据库进行插入/删除时,我注意到应用信息页面中适当的用户数据大小发生了变化。通过createFromAsset 使用的预打包数据库是否被视为缓存?感谢您抽出宝贵时间。 @lexler createFromAsset 的最终结果是一个普通/没有什么特殊的数据库。实际问题是什么?即,只要数据可以访问,为什么数据所在的位置很重要? 嗯,我认为存储在缓存中的文件是临时的;如果用户希望释放其存储空间,可以安全删除的文件。我遇到的问题不会影响我的应用程序,因为当缓存被清除时,数据会以某种方式重新生成,但我认为我的预打包数据库被视为缓存是不寻常的。所以我想知道这是否是 ROOM 的预期行为

以上是关于Android Room 将预打包的数据库存储在缓存中是不是正常?的主要内容,如果未能解决你的问题,请参考以下文章

android 开发进程 0.37 room数据存储的使用

Android 数据存储-Room

Android 数据存储-Room

Android 数据存储-Room

android Room 数据库存储敏感数据是不是安全?

Android_存储之文件存储