Android - ускорение удаления файлов с помощью Storage Access Framework - PullRequest
0 голосов
/ 02 октября 2019

С 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

1 Ответ

0 голосов
/ 02 октября 2019

При использовании класса File (в Java) папка с 200 файлами .jpg размером около 2,5 МБ каждый удаляется за 5 секунд.

При использовании DocumentsContract это делается за 10 секунд. (50 мс на файл)

Приведите цифры для удаления большой папки.

...