Мне нужно проверить, существует ли определенная директория в apk.
android/asset_manager.h
API кажется несовместимым — он возвращает NULL, когда AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode);
не удается открыть файл, но для каталогов AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName);
Реализация всегда возвращает new AAssetDir(...)
, даже если внутренне не удалось открыть / найти каталог в apk.
Это довольно раздражает, что AAssetDir
объявлен заранее, и его реализация скрыта в файле .cpp, иначе было бы (возможно?) возможно проверить внутренний AssetDir
Объект для действительности.
Есть еще один вариант, который я сейчас изучаю — вызвать java и сделать что-то вроде:
public static boolean folderExistsInApk(final String path){
AssetManager assetManager = activity.getAssets();
try{
//if .list would fail, it would throw IOException
//which would signal that there is no such directory
assetManager.list(path);
}catch(Exception e){
return false;
}
return true;
}
Но мне это кажется «грязным» и определенно будет довольно медленным (что не является большим фактором в моем конкретном коде, но все же — избегать ненужной пессимизации — хорошая практика кодирования).
Я что-то пропустил? Можно ли проверить, существует ли каталог в apk только через собственный код? Если нет — как лучше сделать это с JNI?
Следующий код позволяет проверить, существует ли определенная папка в комплекте apk:
#include <android/asset_manager.h>
bool directoryExists(jobject assetManager, const std::string& path){
auto assetDir = AAssetManager_openDir( assetManager, path.c_str() );
bool r = AAssetDir_getNextFileName(assetDir) != NULL;
AAssetDir_close( assetDir );
return r;
}
AAsetManager_openDir
всегда будет возвращать указатель на инициализированный объект, даже если указанный каталог не существует. Другими словами, проверка, если assetDir==NULL
бессмысленно. Хитрость в том, чтобы проверить, AAssetDir_getNextFileName
вернет ненулевой const char *
, Если это NULL
— нет папки, остальное — есть.
Важное замечание: если папка пуста, но по какой-то причине вам необходимо знать, существует ли она в apk, этот код будет бесполезен из-за способа проверки наличия папки. Но пустые папки AFAIK не копируются в apk, поэтому такая ситуация маловероятна.