如何有效地列出目录中的所有文件,包括子目录? [英] How to list all files inside a directory including sub-directories efficiently?
问题描述
我正在开发一个图库应用,该应用可显示手机或笔式驱动器中的所有图像.我成功地列出了所有图像并将其显示到应用程序中.但我认为它很慢.我在 AsyncTask
中使用了 Depth First Search
技术.那么有没有其他方法可以在 AsyncTask
中使用,它的速度要快得多.这里的根是一个由树 URI 组成的 DocumentFile.
I'm working on a gallery app which displays all the images in a phone or a pen-drive. I successfully managed to list all the images and displays it into the app. But I think it is pretty slow. I'm using Depth First Search
technique inside an AsyncTask
. So is there any other method which can be used inside AsyncTask
which is much faster.
Here root is a DocumentFile which is made from a tree URI.
这是我使用过的代码.
public class ImageBackgroundTask extends AsyncTask<Object, Object, ArrayList<DocumentFile>> {
DocumentFile root;
ArrayList<DocumentFile> result;
ProgressDialog pg;
Context context;
private AsyncTaskCompleteListener<ArrayList<DocumentFile> > callback;
ImageBackgroundTask(DocumentFile root, Context context, AsyncTaskCompleteListener<ArrayList<DocumentFile>> cb){
this.context=context;
this.root=root;
this.callback = cb;
}
@Override
protected ArrayList<DocumentFile> doInBackground(Object... voids) {
Queue<DocumentFile> stack=new ArrayDeque<>();
ArrayList<DocumentFile> list=new ArrayList<>();
for(DocumentFile f:root.listFiles()){
stack.add(f);
}
while(!stack.isEmpty()){
DocumentFile child=stack.remove();
if(child.isDirectory()){
for(DocumentFile file:child.listFiles()){
stack.add(file);
}
}
else if(child.isFile()){
String name=child.getName();
if(name.endsWith(".jpg")
|| name.endsWith(".png")
|| name.endsWith("jpeg")
|| name.endsWith("JPG")
|| name.endsWith("JPEG")
|| name.endsWith("PNG"))
list.add(child);
}
}
return list;
}
@Override
protected void onPreExecute() {
pg=new ProgressDialog(context);
pg.setMessage("Loading...");
pg.show();
}
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(ArrayList<DocumentFile> aVoid) {
pg.dismiss();
result=aVoid;
callback.onTaskComplete(result);
}
这是输出.
推荐答案
不要使用 DocumentFile.listFiles()
列出您使用 Intent.ACTION_OPEN_DOCUMENT_TREE<获取的树 uri 的文件/代码>.
Do not use DocumentFile.listFiles()
to list the files for a tree uri you obtained with Intent.ACTION_OPEN_DOCUMENT_TREE
.
因为它是出了名的慢.
改为使用 DocumentsContract
中的函数.
Instead use functions from DocumentsContract
.
查看 使用 MTP 使用 Android Storage Access Framework/DocumentProvider 遍历目录层次结构的问题
Look at the void traverseDirectoryEntries(Uri rootUri)
function from Issues traversing through directory hierarchy with Android Storage Access Framework / DocumentProvider using MTP
为每个文件收集子 uri,而不是尝试为其获取 DocumentFile.
Collect the child uri for every file instead of trying to obtain a DocumentFile for it.
然后您可以使用该子 uri 加载图像.
Then later you can use that child uri to load the image.
如果你现在需要六秒钟,那么我认为 DocumentsContract 不到一秒钟.
If you need six seconds now then it will be less than a second with DocumentsContract i think.
这篇关于如何有效地列出目录中的所有文件,包括子目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!