6

C/C++ コード内から、assets フォルダー内のアセットを操作する必要があります。このように 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 はメイン アクティビティ (UI スレッド) の Java onCreate メソッドから呼び出されますが、C/C++ での使用は、GLSurfaceView 実装のネイティブ メソッドから呼び出されるレンダリングとゲーム ティックをネイティブに処理する場合です。

1) assetMgr ポインターは、アプリの有効期間全体で有効なオブジェクトを指しますか? ガベージ コレクターが破棄しないように、Java 側 (アクティビティ クラス) の静的変数のように作成するだけで十分ですか?

2) スレッドで問題が発生する危険性はありますか?

ありがとう、トム・アトム

4

2 に答える 2

3

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

そのためには、 を呼び出しますenv->NewGlobalRef(assetManager)

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

于 2012-06-19T15:29:48.840 に答える
2

私は NDK モジュールAssetbridgeを作成しました。これも役立つかもしれません。プロジェクトの assets/ フォルダー (ファイルとディレクトリ) の内容を一時ディレクトリにエクスポートし、環境変数をそのパスに設定するため、ネイティブ コードは一時ディレクトリに chdir() でき、通常の古い標準を使用できます。ライブラリ ファイル IO ルーチン。

于 2013-06-25T08:02:26.550 に答える