本文介绍了如何有效列出目录中包括子目录的所有文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用图库应用程序,该程序可以在手机或笔式驱动器中显示所有图像.我成功地列出了所有图像并将其显示在应用程序中.但我认为这很慢.我在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);

}

这是输出.

签出GIF

推荐答案

请勿使用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中的功能.

中查看void traverseDirectoryEntries(Uri rootUri)函数使用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.

这篇关于如何有效列出目录中包括子目录的所有文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 13:23