2017-02-12 374 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返回。