android - 在使用位图类型转换器类时从 ROOM 数据库中多次查询行会使应用程序崩溃
问题描述
所以我有一个带有分页适配器的 Recycler View,recycler view 列表项有一个 imageView 和几个文本视图。适配器正在从另一个 ROOM 数据库中检索 textViews 的数据,而从另一个 ImageHolder ROOM 数据库中检索每个特定列表项的图像。
在适配器的 onBind 方法中,除了绑定 textViews 之外,还有对关联图像的 ImageHolder ROOM 数据库的单独调用。Recycler View 有大约 100 个项目,当 UI 快速滚动时,对 ImageHolder 数据库进行了大约 100 个查询。这很好用,但是当用户滚动并崩溃应用程序时,它会减慢应用程序的速度。我该如何避免崩溃?
这是代码:
数据类
@Entity(tableName = IMAGE_HOLDER_TABLE)
data class ImageHolder(
@PrimaryKey(autoGenerate = false)
var contentId: String = "",
var imageBitmap : Bitmap, // I am using a Converter class to convert a Bitmap to a ByteArray
var timeStamp : Long = System.currentTimeMillis()
)
道接口
@Dao
interface ImageHolderDatabaseDao {
@Query("SELECT * FROM $IMAGE_HOLDER_TABLE WHERE contentId = :contentId")
suspend fun getImageHolder(contentId : String): ImageHolder
@Query("SELECT imageBitmap FROM $IMAGE_HOLDER_TABLE WHERE contentId =
:contentId")
suspend fun getImage(contentId : String): Bitmap
}
Adapter的onBindViewHolder方法中获取图片的方法
val imageHolderDatabase = ImageHolderDatabase.instance(getApplicationContext())
val imageHolderDatabaseDao = imageHolderDatabase.databaseDao
private val scope = CoroutineScope(Dispatchers.Main +
CoroutineName("notificationsAdapterCoroutine"))
private fun populatePhotoFromLocalDb(senderUserId : String) {
scope.launch {
val imageBitmap = imageHolderDatabase.withTransaction {
imageHolderDatabaseDao.getImageHolder(senderUserId)
}
Glide.with(getApplicationContext())
.load(imageBitmap.imageBitmap)
.placeholder(R.drawable.black_color_rectangle)
.apply(glideRequestOptionsForCache)
.transition(DrawableTransitionOptions.withCrossFade(glideCrossFadeDuration))
.listener(glideFinishedLoadingListener(senderUserId, true, null))
.into(binding.image)
}
}
//I am using the Paging 3 adapter to populate the textViews from another Room Database
我意识到对 ImageHolder Room 数据库进行了 100 次查询调用,因为 Recycler 视图中有 100 个项目。我正在使用 Glide 但现在不使用它的缓存。
什么是内存有效的方法来做到这一点?
解决方案
从 ByteArray 到 Bitmap 的类型转换器导致过多的内存使用,这实际上是存储图像的好方法,但使用方便的 ROOM 类型转换器的用例错误(除非它用于非 recyclerView 适配器),我有更改了逻辑以仅将 downloadUrls 存储在 Room Db 中,并使用 glide 通过下载 Url 加载图像,因为 glide 内置了离线缓存系统,即使互联网暂时不可用,此逻辑也适用...
推荐阅读
- batch-file - 如何从批处理文件中的文件夹名称中提取和使用信息(值、字符串)...
- css - Angular: ng-bootstrap - 带有动画的垂直轮播
- r - 如何将 data.frame(已加载到 R)转换为将创建它的 R 脚本命令,包括数据?
- python - 使用 beautifulsoup 将多个 findall 语句格式化为数据框
- python-3.x - 如何在 python 中为时间序列数据中的组计算 SMAPE?
- python - 重载相等运算符
- python - 从 pyenv-virtualenv 切换到 pipenv 时保持相同的共享虚拟环境
- r - 基于多列匹配合并多个数据框
- python - 有没有办法定义依赖于内容的 CNN/Keras 接受域
- c++ - 如何在 Google Test 中为具有不同模板的多个模板类测试相同的行为?