Мне нужно работать с активами в моей папке с ресурсами из кода C/С++. Безопасно ли кэшировать указатель на AAssetManager, как это...:
AAssetManager* assetMgr = NULL;
void Java_com_example_createAssetManager(JNIEnv* env, jclass clazz, jobject assetManager)
{
AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
assert(NULL != mgr);
assetMgr = mgr;
}
... а затем использовать его всякий раз, когда мне это нужно? CreateAssetManager вызывается из метода Java onCreate основной активности (поток пользовательского интерфейса), но использование в C/С++ заключается в том, что при обработке nativly рендеринга и тика игры из собственных методов в реализации GLSurfaceView.
1) указатель assetMgr указывает на действительный объект durin для всего приложения? Достаточно ли его создать так же, как статическая переменная на стороне Java (в классе Activity), поэтому сборщик мусора не уничтожит его?
2) есть ли какая-то опасность, я столкнусь с некоторыми проблемами с потоками?
Спасибо, Том Атом
Одним из наиболее безопасных способов кэширования диспетчера активов будет сохранение глобальной ссылки на основной объект Java на стороне C вместе с кэшированным указателем AAssetManager
. По крайней мере, с этим вы бы знали, что объект Java за/вокруг объекта C не будет собирать мусор.
Для этого вызовите env->NewGlobalRef(assetManager)
.
И доступ к менеджеру активов по границе потока будет довольно сумасшедшим, ИМХО. Это очень сильное конструктивное ограничение - если не указано явно, безопасность потоков никогда не может быть принята по умолчанию.
Я написал модуль NDK, Assetbridge, который также может оказаться полезным. Он экспортирует содержимое ваших активов/папок проекта (файлов и каталогов) во временный каталог и затем устанавливает переменную окружения в этот путь, поэтому ваш собственный код может chdir() в каталог temp, и вы можете использовать обычный старый стандарт библиотеки IO.
AAssetManager_fromJava()
очень быстрый.