С Android 11 будет невозможно манипулировать файлами в общедоступных местах без SAF. В прошлом я реализовывал два варианта работы с файлами на Android, если файл НЕ находится на SDCard, тогда я использую стандартный API C ++, очень быстрый способ. Если находится на SDCard, то я использую SAF API - я вызываю Java-методы с JNI. Это работало нормально, потому что, если кому-то требовался быстрый доступ, тогда файлы помещались во внутреннее хранилище, если кому-то не хватало места, тогда предпочтительным было место для хранения на SDCard за счет производительности. Однако Android 11 меняет все и первый выбор убит. Я не могу поместить файлы в личную папку, потому что удаляется во время удаления. Мой вопрос касается удаления файлов, потому что в моем случае это самая большая скорость горлышка бутылки. Просто сейчас я удаляю файл следующим образом:
С SAF: DocumentsContract.deleteDocument
Со стандартным API c ++: unlink
Хотя удаление не занимает почти времени, SAF требует 150 мс для удалениямаленький, всего несколько килобайт большой файл.
Это сравнение было проверено на SDCard в личной папке с unlink, в которой у меня полный доступ, и в общей папке с DocumentsContract.deleteDocument.
Is DocumentsContract.deleteDocumentединственный способ, как удалить файл с помощью SAF или есть более быстрый способ, который может вернуть потерянную производительность?
РЕДАКТИРОВАТЬ:
Я добавляю больше информации. Я рутировал и добавил sdcard fix, так что теперь я могу писать напрямую на sdcard. Мое приложение - эмулятор, я не удаляю большую папку, это не мой случай, эмулятор тут и там удаляет различное количество файлов небольшого размера. Вот реальный журнал и как я его использую:
Стандартный c ++ IO API
unlink(file);
SAF API C ++
jstring string=jvmEnv->NewStringUTF(file);
int result = jvmEnv->CallIntMethod( jvmCallbackThread, JavaDeleteFile, string);
jvmEnv->DeleteLocalRef(string);
Java
public int callbackDeleteFile(String path) {
return SAFUtils.delete(path);
}
public static int delete(String path)
{
try {
Uri uri = pathsCache.get(path);
if (uri == null) {
buildUri(path, true);
uri = Uri.parse(builder1.toString());
pathsCache.put(path, uri);
}
if (DocumentsContract.deleteDocument(resolver, uri)) {
return 0;
}
} catch(Exception e) {
e.printStackTrace();
}
return -1;
}
На стороне Java я получаю / собираю URI, после этого я вызываю DocumentContract, манипуляция URI занимает около 1 мс, узким местом является DocumentContract.deleteDocument
2019-10-03 09:20:29.478 before uri get/build
2019-10-03 09:20:29.478 after uri get/build
2019-10-03 09:20:29.674 after DocumentContract.deleteDocument
Вход с SAF:
SAF log означает, перейти с c ++ на java, вызвать DocumentContract.deleteDocument и вернуться к c ++
2019-10-03 08:19:10.039 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/RAW10.ALF, before delete
2019-10-03 08:19:10.253 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/RAW10.ALF, after delete
2019-10-03 08:19:10.254 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/RAW10.MOD, before delete
2019-10-03 08:19:10.475 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/RAW10.MOD, after delete
2019-10-03 08:19:12.602 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/LOC_GODS.DAT, before delete
2019-10-03 08:19:12.786 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/LOC_GODS.DAT, after delete
2019-10-03 08:19:12.829 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/UNP.$$$, before delete
2019-10-03 08:19:12.990 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/UNP.$$$, after delete
2019-10-03 08:19:13.076 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/LOC_DEIT.DAT, before delete
2019-10-03 08:19:13.221 : SAF DeleteFile /storage/0000-0000/TEST/TEMP/LOC_DEIT.DAT, after delete
Журнал с unlink
pure c ++ side
2019-10-03 08:58:03.008 : UNLINK /storage/0000-0000/TEST/TEMP/RAW10.ALF, before unlink
2019-10-03 08:58:03.009 : UNLINK /storage/0000-0000/TEST/TEMP/RAW10.ALF, after unlink
2019-10-03 08:58:03.010 : UNLINK /storage/0000-0000/TEST/TEMP/RAW10.MOD, before unlink
2019-10-03 08:58:03.010 : UNLINK /storage/0000-0000/TEST/TEMP/RAW10.MOD, after unlink
2019-10-03 08:58:05.084 : UNLINK /storage/0000-0000/TEST/TEMP/LOC_GODS.DAT, before unlink
2019-10-03 08:58:05.085 : UNLINK /storage/0000-0000/TEST/TEMP/LOC_GODS.DAT, after unlink
2019-10-03 08:58:05.099 : UNLINK /storage/0000-0000/TEST/TEMP/UNP.$$$, before unlink
2019-10-03 08:58:05.099 : UNLINK /storage/0000-0000/TEST/TEMP/UNP.$$$, after unlink
2019-10-03 08:58:05.116 : UNLINK /storage/0000-0000/TEST/TEMP/LOC_DEIT.DAT, before unlink
2019-10-03 08:58:05.116 : UNLINK /storage/0000-0000/TEST/TEMP/LOC_DEIT.DAT, after unlink