android - 如何提高 Android 中的内容解析器查询速度?
问题描述
我想显示包含图像/视频的文件夹列表。另外,我想获取该文件夹中图像/视频的数量,最近的图像/视频。我还想在列表顶部显示相机、所有媒体和所有视频文件夹,如 WhatsApp。
fun getImageBuckets(mContext: Context) {
viewModelScope.launch(Dispatchers.IO) {
imageFolderList.clear()
val uri = MediaStore.Files.getContentUri("external")
val projection = arrayOf(
MediaStore.Files.FileColumns._ID,
MediaStore.Files.FileColumns.BUCKET_DISPLAY_NAME,
MediaStore.Files.FileColumns.DATA,
MediaStore.Files.FileColumns.MIME_TYPE
)
// Return only video and image metadata.
val selection = (MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE
+ " OR "
+ MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO)
val order = MediaStore.Files.FileColumns.DATE_ADDED
val cursor: Cursor? =
mContext.contentResolver.query(uri, projection, selection, null, order)
var path = ""
var id: Long
var bucketPath: String? = null
var bucketCompletePath: String
var bucketCameraPath = ""
var mimeType: String
var imageDetail: ImageDetail
val cameraPathName =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
.toString() + "/Camera"
val folderMap: MutableMap<String, FolderDetail> = mutableMapOf()
val allMedias: MutableList<ImageDetail> = mutableListOf()
val allVideos: MutableList<ImageDetail> = mutableListOf()
if (cursor != null) {
val allMedia = FolderDetail("All media", path, 0, MediaFolderType.ALL_MEDIA)
val allVideo = FolderDetail("All videos", path, 0, MediaFolderType.ALL_VIDEO)
if (cursor.moveToLast()) {
do {
id = cursor.getLong(0)
bucketPath = cursor.getString(1)
path = cursor.getString(2)
mimeType = cursor.getString(3)
// val file = ImagePickerUtils.makeSafeFile(path) ?: continue
if (bucketPath == null) {
val parent = File(path).parentFile
bucketPath = if (parent != null) {
parent.name
} else {
PickerConstants.EMPTY_STRING
}
}
imageDetail = ImageDetail(id, path)
allMedias.add(imageDetail)
if (bucketPath != null) {
bucketCompletePath = path.substringBeforeLast("/")
var folder = folderMap[bucketCompletePath]
if (folder == null) {
if (path.contains(cameraPathName, true)) {
bucketCameraPath = bucketCompletePath
folder =
FolderDetail(bucketPath, path, 0, MediaFolderType.CAMERA)
folderMap[bucketCompletePath] = folder
} else {
folder =
FolderDetail(bucketPath, path, 0, MediaFolderType.FOLDER)
folderMap[bucketCompletePath] = folder
}
}
folder.images.add(imageDetail)
if (mimeType.contains("video", true)) {
allVideos.add(imageDetail)
}
}
} while (cursor.moveToPrevious())
cursor.close()
if (allMedias.isNotEmpty()) { // Check and Add top 3 folders has data then add at top
allMedia.images.addAll(allMedias)
allMedia.firstImagePath = allMedias[0].path
imageFolderList.add(allMedia)
if (allVideos.isNotEmpty()) {
allVideo.images.addAll(allVideos)
allVideo.firstImagePath = allVideos[0].path
imageFolderList.add(allVideo)
}
if (bucketCameraPath.isNotBlank()) {
val cameraMedia = folderMap[bucketCameraPath]
folderMap.remove(bucketCameraPath)
imageFolderList.add(0, cameraMedia!!)
}
}
imageFolderList.addAll(folderMap.values)
}
}
getFolderListDiffResult()
}
}
这是用于实现此目的的代码,读取 9000 个媒体文件需要 200 毫秒。我想进一步提高逻辑性能。上述代码的任何性能输入?
解决方案
推荐阅读
- rest - SAP PI RFC 到 REST 通信,无需映射。可能的?
- oracle - 从数据库查询中发送带有新记录的电子邮件
- github - 通过 GitHub API 访问链接的 SAML 身份
- java - 将文本输入编辑到数组中
- java - 下一个活动android中仍然存在启动画面
- c++ - 具有 std::map 和 std::variant 的不完整类型
- bar-chart - 如何在 Tableau 中显示最近几天的数据但从一开始就累积记录
- xslt - XSLT:从 for-each/select 中删除“”标签
- java - 方法效率低下
- java - 如何从 HashMap 中获取字符串键?