为什么DocumentFile.getName()方法执行耗时相对较长?
DocumentFile单实例属性方法耗时高于listFiles的原因
核心原因来自DocumentFile的底层实现逻辑与Android跨进程调用的固有开销:
listFiles()采用批量IPC机制:调用该接口时,系统仅发起1次存储访问框架(SAF)的跨进程请求,批量拉取目标目录下所有文件的URI并生成对应DocumentFile实例返回,无重复IPC开销,因此即便返回250个实例也仅需百毫秒级耗时。- 单实例属性方法为单次IPC调用:默认
DocumentFile实现采用懒加载逻辑,实例初始化时仅存储对应文件的URI,不会预加载文件元数据。每次调用isDirectory()、getName()这类属性方法时,都会单独触发1次Binder IPC请求,调用系统ContentProvider查询对应文件的元数据,单次IPC耗时通常在10ms左右,250个文件累计调用500次方法对应总耗时就会达到5000ms量级。
优化方案
可绕过DocumentFile单实例属性方法,直接通过ContentResolver发起批量查询,仅需1次IPC即可拉取所有需要的文件元数据,大幅降低耗时:
ContentResolver resolver = context.getContentResolver(); Uri dirUri = dfDir.getUri(); // 指定需要查询的元数据列 String[] projection = new String[] { DocumentsContract.Document.COLUMN_DISPLAY_NAME, DocumentsContract.Document.COLUMN_MIME_TYPE }; try (Cursor cursor = resolver.query(dirUri, projection, null, null, null)) { while (cursor != null && cursor.moveToNext()) { // 直接从游标获取所有需要的属性,无需额外IPC String fileName = cursor.getString(0); String mimeType = cursor.getString(1); boolean isDir = DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType); // 后续业务逻辑 } }
内容的提问来源于stack exchange,提问作者Hong
相关产品推荐
相关产品推荐

