ContentResolver.openAssetFileDescriptor() 在 Android 12 中需要很长时间

Posted

技术标签:

【中文标题】ContentResolver.openAssetFileDescriptor() 在 Android 12 中需要很长时间【英文标题】:ContentResolver.openAssetFileDescriptor() takes a long time in Android 12 【发布时间】:2021-12-29 06:09:01 【问题描述】:

android 12 中,此方法调用需要几秒钟才能返回:

val descriptor = contentResolver.openAssetFileDescriptor(rootUri, "r")

我正在向它传递一个树 Uri,它代表 USB 驱动器的根。调用需要更长的时间,具体取决于根上占用了多少空间。所以对于 1GB,大约需要 10 秒。在以前的 Android 版本中情况并非如此,调用只需几毫秒即可返回。

我的目标是使用以下代码测量 USB 驱动器上的空间。我还能做些什么来在合理的时间内完成这项工作吗?

val descriptor = contentResolver.openAssetFileDescriptor(rootUri, "r")
val stats = Os.fstatvfs(descriptor!!.fileDescriptor)
val availableSpace = stats.f_bavail * stats.f_bsize

Relevant link

Google Issue tracker link with sample project

【问题讨论】:

您的代码中有三个调用。不清楚你是否只抱怨第一次来电。 @blackapps 问题出在contentResolver.openAssetFileDescriptor() 调用上。我包含其余代码只是为了为我想要实现的目标提供上下文。如果我测量这三条线中的每一条,第一条需要几秒钟,而另外两条几乎是瞬时的。 文件数量有影响吗?或者占用的空间量?我发现上面有很多文件的笔式驱动器需要更长的时间才能挂载。 是的,似乎是这样。在我运行 Android 12 的 Pixel 6 上,8 GB 的图片需要 18 秒,而 8 GB 的大视频需要 1.5 秒。但在我运行 Android 9 的 Pixel 2 上,这些操作分别只需要 30 毫秒和 8 毫秒。 【参考方案1】:

对于 Android 12,您可以请求原始文件访问权限。 (忘记正确的权限名称)

当您执行所有文件操作时,都会经过媒体存储。

值得一试。

【讨论】:

我认为您指的是MANAGE_EXTERNAL_STORAGE,它启用了“所有文件访问”。不幸的是,这似乎不能解决问题。我仍然需要将Uri 转换为ParcelFileDescriptor,而且这个权限似乎并没有加快任何方法的速度(这些方法都是ContentResolver 的一部分)。 那是“所有文件访问”。不,我没有提到那个。里面有一个RAW。 (抱歉,我现在正躺在棕榈树下 ;-) 手头没有代码) android:requestRawExternalStorageAccess="true 在清单文件的应用程序标记中。 developer.android.com/reference/android/… 不幸的是,启用它对速度没有影响。但我很欣赏这个建议! 你只需要Os.statvfs的路径。

以上是关于ContentResolver.openAssetFileDescriptor() 在 Android 12 中需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章