Я внедряю новый API Storage Access Framework в свое приложение. Кажется, что все работает хорошо, за исключением одной мелочи. Когда я использую сборщик документов, чтобы открыть файл из моего собственного приложения (скажем, из другой учетной записи в приложении), openDocument
в моей реализации DocumentsProvider
вызывается в основном потоке. Это нормально, если запрошенный файл был кэширован локально, но если это не так, то выполняется сетевой запрос, результатом которого является NetworkInMainThreadException
. Интересно отметить, что в документации упоминается «Это нормально, чтобы выполнять сетевые операции в этом методе для загрузки документа». Это известная ошибка, и если да, то кто-нибудь знает об этом?Android DocumentsProvider: openDocument вызывается в основном потоке
Вот мой код для запуска сборщика:
Intent target = new Intent(Intent.ACTION_OPEN_DOCUMENT);
target.setType("*/*");
target.addCategory(Intent.CATEGORY_OPENABLE);
final Intent intent = Intent.createChooser(target, getString(R.string.document_choose));
try {
startActivityForResult(intent, SELECT_FILE_REQUEST_CODE);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
Затем, когда пользователь выбрал файл, это примерно как я обрабатывать openDocument
:
@Override
public ParcelFileDescriptor openDocument(final String documentId, String mode,
CancellationSignal signal) throws FileNotFoundException {
final File file = getFileFromId(documentId);
if(!file.exists()) {
// This is where I have problems
if("main".equalsIgnoreCase(Thread.currentThread().getName())) {
throw new FileNotFoundException("File has not been cached locally.");
} else {
downloadFile(app, file, document, folder);
}
}
}
Обратите внимание на проверку для того вызова на основной нити. Этого не происходит, когда внешнее приложение использует мое приложение для выбора файла, так как openDocument
затем вызывается в фоновом потоке. Это происходит только тогда, когда я пытаюсь выбрать файл из своего собственного приложения (но из другой учетной записи и, следовательно, другого ROOT).
Однако, когда я попытался сделать то же самое на Google Диске (то есть, запустил приложение, а затем использовал свой собственный сборщик, чтобы выбрать файл), он, казалось, мог загрузить файл по сети без сбоев приложение.
Но некоторые из таких приложений, как Gmail, делают это на главной теме, что приведет к сбою в так называемом NetworkInMainThreadException. – Boopathy