2012-06-19 15 views
6

C/C++コード内から自分のアセットフォルダ内のアセットを操作する必要があります。このようにAAssetManagerへのポインタをキャッシュするのは安全ですか?:Android NDK - AssetManagerをネイティブコードで使用する

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は、メインアクティビティ(UIスレッド)のJava onCreateメソッドから呼び出されますが、C/C++での使用方法は、GLSurfaceView実装でネイティブメソッドからレンダリングとゲームティックをネイティブに処理するときです。

1)assetMgrポインタが有効なオブジェクトを指していますか?それはガベージコレクタがそれを破壊しないように、Java側の静的変数(Activityクラス内)のようにも作成するのに十分ですか?

2)スレッドにいくつかの問題が発生する危険性がありますか?

おかげで、トムアトム

+0

安全面でエラーが発生し、キャッシュされません。 'AAssetManager_fromJava()'は非常に高速です。 –

+0

ありがとうございます。私がキャッシュしたいのは、メソッド呼び出しで "jobject assetManager"を持たずにポインタを取得する方法がわからないからです。だから、このパラメータをJavaからC/C++へのすべてのティックコールに追加しなければならないのですか?または、私がそれを必要とするときにオブジェクトのJavaをどのように問い合わせることができるか(AssetManagerのJavaに依頼してから、AAssetManager_fromJavaを呼び出して使用する) –

答えて

3

アセット・マネージャーは、キャッシュされたAAssetManagerポインタと一緒にC側の基盤となるJavaオブジェクトへのグローバル参照を保持することであろうキャッシュするための一つのわずかに安全な方法。少なくとも、Cオブジェクトの背後/周囲のJavaオブジェクトはガベージコレクションされないことがわかります。

これを行うには、に電話してください。

スレッド境界を越えてアセットマネージャにアクセスすることは、むしろ夢中になるでしょう。これは非常に強力な設計上の制約です。明示的に文書化されない限り、スレッドの安全性は決してデフォルトでは想定できません。

2

私はNDKモジュールAssetbridgeを書いていますが、役に立つと思うかもしれません。プロジェクトのアセット/フォルダ(ファイルとディレクトリ)の内容を一時ディレクトリにエクスポートし、そのパスに環境変数を設定すると、ネイティブコードで一時ディレクトリにchdir()を実行できるようになり、通常の古い標準ライブラリファイルIOルーチン。

関連する問題