Android NDK - использование AssetManager в нативном коде

6

Мне нужно работать с активами в моей папке с ресурсами из кода 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) есть ли какая-то опасность, я столкнусь с некоторыми проблемами с потоками?

Спасибо, Том Атом

  • 0
    Ошибся в безопасности и не кешируй. AAssetManager_fromJava() очень быстрый.
  • 0
    Спасибо за ответ. Причина, по которой я хотел кешировать, заключалась в том, что я не знаю, как получить указатель, не имея "jobject assetManager" в вызове метода. Итак, нужно ли добавлять этот параметр в каждый тиковый вызов с Java на C / C ++ только на тот случай, если он понадобится во время тика? Или есть какой-то способ, как я могу запросить Java для объекта во время, когда мне это нужно (спросите Java для AssetManager, затем вызовите AAssetManager_fromJava, затем используйте его ...)
Теги:
thread-safety
android-ndk
android-assets

2 ответа

3
Лучший ответ

Одним из наиболее безопасных способов кэширования диспетчера активов будет сохранение глобальной ссылки на основной объект Java на стороне C вместе с кэшированным указателем AAssetManager. По крайней мере, с этим вы бы знали, что объект Java за/вокруг объекта C не будет собирать мусор.

Для этого вызовите env->NewGlobalRef(assetManager).

И доступ к менеджеру активов по границе потока будет довольно сумасшедшим, ИМХО. Это очень сильное конструктивное ограничение - если не указано явно, безопасность потоков никогда не может быть принята по умолчанию.

2

Я написал модуль NDK, Assetbridge, который также может оказаться полезным. Он экспортирует содержимое ваших активов/папок проекта (файлов и каталогов) во временный каталог и затем устанавливает переменную окружения в этот путь, поэтому ваш собственный код может chdir() в каталог temp, и вы можете использовать обычный старый стандарт библиотеки IO.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню