2017-02-12 381 views
1

我想创建类似“PDF查看器应用程序”的东西。应用程序将搜索用户选择的位置中的所有* .pdf文件。用户可以通过此功能选择这个文件夹:DocumentFile非常慢

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); 
startActivityForResult(intent, REQUEST_CODE); 

然后我得到DocumentFile(文件夹):

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (resultCode == getActivity().RESULT_OK && requestCode == REQUEST_CODE) { 
     Uri uriTree = data.getData(); 
     DocumentFile documentFile = DocumentFile.fromTreeUri(getActivity(), uriTree); 
     //rest of code here 
    } 
} 

为什么我选择了选择文件夹的这种方法吗?因为我希望能够选择辅助存储(您知道,在Android> = 5.0中,您不能使用Java.io.file访问辅助存储)。

好了,我得到的文件夹中所有的* .pdf为DocumentFile。然后我打电话:

for(DocumentFile file: documentFile.listFiles()){ 
    String fileNameToDisplay = file.getName(); 
} 

这是很慢。当所选文件夹中有〜600个文件时,需要将近30秒。为了证明这一点,我选择了外部存储(不是辅助存储)的目录,然后尝试了两种解决方案:DocumentFile和File。 文件版本看起来像:

File f = new File(Environment.getExternalStorageDirectory()+"/pdffiles"); 
    for(File file: f.listFiles()){ 
     String fileNameToDisplay = file.getName(); 
    } 
} 

第二个版本的作品约500倍的速度更快。几乎没有时间显示列表视图上的所有文件。为什么DocumentFile这么慢?

+1

'为什么DocumentFile这么慢?'。错误的问题。你应该问'我应该用什么来代替DocumentFile?'。那么只有当你想要更快的东西;-)。 – greenapps

+0

DocumentFile的listFiles()已经比文件的慢。但DocumentFile.getName()非常慢。 Soooo slooow。 – greenapps

+0

是啊,我应该问这样的,但现在我不能改变它:( – user2551317

回答

0

DocumentFile为什么这么慢?一个ContentProvider

对于〜600个文件要执行〜600请求获得的显示名称,这意味着〜600个IPC交易。

取而代之,请使用MediaStore来查询application/pdf MIME类型的所有索引媒体。

0

要获得小于File的速度,请使用DocumentsContract而不是DocumentFile来列出使用Intent.ACTION_OPEN_DOCUMENT_TREE获得的树木的内容。

+0

谢谢回答!但是我怎么可以使用DocumentsContract列出子目录/文件? – user2551317

+0

我觉得有点谷歌搜索就行了。少那么双几个月前上市代码被张贴在这里。 – greenapps

0

要使用DocumentsContract获得子女的文件,见https://developer.android.com/reference/android/provider/DocumentsContract.html#buildChildDocumentsUriUsingTree(android.net.Uri,java.lang.String中)。

的URI从ACTION_OPEN_DOCUMENT_TREE返回是一棵树文件URI。使用上述方法构建Uri以查询所有子文档。

根文档ID可以使用https://developer.android.com/reference/android/provider/DocumentsContract.html#getTreeDocumentId(android.net.Uri)获得,Uri从ACTION_OPEN_TREE_DOCUMENT返回。