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

Мне нужно работать с активами в моей папке assets из кода C/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 основной активности (UI thread), но использование в C/C++ - это когда nativly обработка рендеринга и игровой ТИК вызываются из собственных методов в реализации GLSurfaceView.

1) будет ли указатель assetMgr указывать на действительный объект во время всего жизненного цикла приложения? Достаточно ли создать его также как статическую переменную на стороне Java (в классе Activity), чтобы сборщик мусора не уничтожил его?

2)есть ли опасность, что я столкнусь с некоторыми проблемами с потоками?

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

2 ответов


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

чтобы сделать это, позвоните env->NewGlobalRef(assetManager).

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


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