Run Import/Export on non-UI thread

This seems to fix Android sometimes throwing
NetworkOnMainThreadException when importing bit files through the
Nextcloud app.

I'm not sure if this is necessary for the export too, but it doesn't
seem to break anything so for consistency it makes sense to also wrap
the exporter into a thread.

This change is suboptimal because it will still block the UI with a
ProgressDialog (which is deprecated) and force the user to wait until
the import/export completes (and will kill the import/export if the app
gets backgrounded) but it should at least fix the most common crash for
most users.
This commit is contained in:
Sylvia van Os
2024-05-21 21:01:42 +02:00
parent 4b1d1f4541
commit edeb95aee0
2 changed files with 31 additions and 17 deletions

View File

@@ -4,6 +4,7 @@
- Support for creating a card when sharing plain text
- Display image type instead of barcode below images
- Fix possible crash when trying to import a backup from the Nextcloud app
## v2.29.1 - 135 (2024-05-19)

View File

@@ -80,15 +80,21 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
Log.e(TAG, "Activity returned NULL uri");
return;
}
try {
OutputStream writer = getContentResolver().openOutputStream(uri);
Log.e(TAG, "Starting file export with: " + result.toString());
startExport(writer, uri, exportPassword.toCharArray(), true);
} catch (IOException e) {
Log.e(TAG, "Failed to export file: " + result.toString(), e);
onExportComplete(new ImportExportResult(ImportExportResultType.GenericFailure, result.toString()), uri);
}
// Running this in a thread prevents Android from throwing a NetworkOnMainThreadException for large files
// FIXME: This is still suboptimal, because showing that the export started is delayed until the network request finishes
new Thread() {
@Override
public void run() {
try {
OutputStream writer = getContentResolver().openOutputStream(uri);
Log.e(TAG, "Starting file export with: " + result);
startExport(writer, uri, exportPassword.toCharArray(), true);
} catch (IOException e) {
Log.e(TAG, "Failed to export file: " + result, e);
onExportComplete(new ImportExportResult(ImportExportResultType.GenericFailure, result.toString()), uri);
}
}
}.start();
});
fileOpenLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), result -> {
if (result == null) {
@@ -160,14 +166,21 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
}
private void openFileForImport(Uri uri, char[] password) {
try {
InputStream reader = getContentResolver().openInputStream(uri);
Log.e(TAG, "Starting file import with: " + uri.toString());
startImport(reader, uri, importDataFormat, password, true);
} catch (IOException e) {
Log.e(TAG, "Failed to import file: " + uri.toString(), e);
onImportComplete(new ImportExportResult(ImportExportResultType.GenericFailure, e.toString()), uri, importDataFormat);
}
// Running this in a thread prevents Android from throwing a NetworkOnMainThreadException for large files
// FIXME: This is still suboptimal, because showing that the import started is delayed until the network request finishes
new Thread() {
@Override
public void run() {
try {
InputStream reader = getContentResolver().openInputStream(uri);
Log.e(TAG, "Starting file import with: " + uri);
startImport(reader, uri, importDataFormat, password, true);
} catch (IOException e) {
Log.e(TAG, "Failed to import file: " + uri, e);
onImportComplete(new ImportExportResult(ImportExportResultType.GenericFailure, e.toString()), uri, importDataFormat);
}
}
}.start();
}
private void chooseImportType(boolean choosePicker,