2017-02-12 2 views
1

Я хочу создать что-то вроде «Приложение PDF Viewer». Приложение будет искать все * .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(); 
} 

И это ОЧЕНЬ МЕДЛЕННО. Это занимает почти 30 секунд, когда в выбранной папке ~ 600 файлов. Чтобы доказать это, я выбрал каталог из External Storage (не вторичное хранилище), а затем попробовал два решения: DocumentFile и File. версия файла выглядит она:

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

Вторая версия работает около 500x быстрее. При отображении всех файлов в представлении списка почти нет времени.

Почему DocumentFile так медленно?

+1

'Почему DocumentFile так медленно?'. Неверный вопрос. Вы должны спросить: «Что я должен использовать вместо DocumentFile?». Ну только если вы хотите что-то быстрее ;-). – greenapps

+0

ListFiles() DocumentFile уже медленнее, чем файл File. Но очень медленным является DocumentFile.getName(). Soooo slooow. – greenapps

+0

Да, я должен был спросить, как это, но я не могу изменить его прямо сейчас :( – user2551317

ответ

0

Почему DocumentFile так медленно?

Для ~ 600 файлов вы выполняете ~ 600 запросов ContentProvider, чтобы получить отображаемое имя, что означает ~ 600 транзакций IPC.

Вместо этого используйте MediaStore для запроса всех индексированных носителей с типом MIME application/pdf.

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 для запроса всех дочерних документов.

Идентификатор корневого документа может быть получен с использованием https://developer.android.com/reference/android/provider/DocumentsContract.html#getTreeDocumentId(android.net.Uri) с возвратом Uri из ACTION_OPEN_TREE_DOCUMENT.

Смежные вопросы