2012-06-19 9 views
6

Ich muss mit Assets in meinem Assets-Ordner aus dem C/C++ - Code heraus arbeiten. Ist es sicher, Zeiger auf AAssetManager so cachen ...:Android NDK - Verwenden von AssetManager in systemeigenem Code

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;  
} 

... und dann, es zu benutzen, wenn ich sie brauche? Der createAssetManager wird von der Java onCreate-Methode der Hauptaktivität (UI-Thread) aufgerufen, aber die Verwendung in C/C++ erfolgt, wenn nativ das Rendering und das Spielticket von nativen Methoden in der GLSurfaceView-Implementierung aufgerufen werden.

1) Wird der AssetMgr-Zeiger während der gesamten Anwendungslebensdauer auf ein gültiges Objekt zeigen? Ist es genug, um es auch als statische Variable auf der Java-Seite (in der Aktivitätsklasse) zu erstellen, damit der Garbage Collector es nicht zerstört?

2) Gibt es eine Gefahr, dass ich einige Probleme mit Threads bekomme?

Danke, Tom Atom

+0

Err auf der sicheren Seite und nicht zwischenspeichern. 'AAsetManager_fromJava()' ist sehr schnell. –

+0

Vielen Dank für die Antwort. Der Grund, warum ich es zwischenspeichern wollte, war, dass ich nicht weiß, wie man den Zeiger bekommt, ohne "jobject AssetManager" im Methodenaufruf zu haben. Also, muss ich diesen Parameter bei jedem Tick-Aufruf von Java zu C/C++ hinzufügen, nur für den Fall, dass ich ihn während des Ticks brauche? Oder gibt es eine Möglichkeit, wie ich Java für das Objekt rechtzeitig abfragen kann, wenn ich es brauche (fragen Sie Java nach AssetManager, dann rufen Sie AAsetManager_fromJava auf, dann benutzen Sie es ...) –

Antwort

3

Ein geringfügig sichere Weg, um den Asset-Manager cachen wäre ein globalen Verweis auf das zugrunde liegende Java-Objekt auf der C-Seite mit den zwischengespeicherten AAssetManager Zeigern entlang zu halten. Zumindest wüssten Sie, dass das Java-Objekt hinter oder um das C-Objekt nicht als Garbage-Collection behandelt wird.

Um dies zu tun, rufen Sie .

Und Zugriff auf den Asset-Manager über Thread-Grenze wäre ziemlich verrückt, IMHO. Das ist eine sehr starke Design-Einschränkung - wenn nicht explizit dokumentiert, kann Thread-Sicherheit standardmäßig nicht angenommen werden.

2

Ich habe ein NDK-Modul geschrieben, Assetbridge, das Sie möglicherweise auch nützlich finden. Es exportiert den Inhalt des Assets/Ordners (Dateien und Verzeichnisse) Ihres Projekts in ein temporäres Verzeichnis und setzt dann eine Umgebungsvariable auf diesen Pfad, sodass Ihr nativer Code chdir() in das temporäre Verzeichnis und Sie können den regulären alten Standard verwenden Bibliotheksdatei-IO-Routinen.