3

Android の OpenSL ES に問題があります。OpenSL を使用して効果音を再生しています。現在、サウンドを再生するたびに新しいプレーヤーを作成しています。(これがそれほど効率的でないことはわかっていますが、当面は「十分」です。)

しばらく再生すると、次のエラーが発生し始めます。

E/libOpenSLES(25131): Too many objects
W/libOpenSLES(25131): Leaving Engine::CreateAudioPlayer (SL_RESULT_MEMORY_FAILURE)

私は自分の作成/破棄パターンを追跡しており、いつでも未処理のオブジェクトが 4 つを超えることはなく、システム制限の 32 をはるかに下回っています。もちろん、これは破棄が適切に機能していることを前提としています。

今の私の唯一の推測は、プレイヤー オブジェクトをクリーンアップするときに何か間違ったことをしているということです。考えられる問題の 1 つは、Destroy がプレーヤーのコールバックのコンテキストで呼び出されることが多いことです (基本的には、プレーヤーの再生が終了した後にプレーヤーを破棄します)。ただし、これが問題であることを示唆する参照は見つかりません。プレイヤー オブジェクトを「破棄」する以外に、他に行うべきクリーンアップ手順はありますか? インターフェイスも何らかの方法でクリーンアップする必要がありますか?

- 追加した -

さらにテストを重ねた結果、30 番目のプレーヤーが作成された後も一貫して発生します (エンジンとミックスもあり、合計で 32 オブジェクトになります)。したがって、オブジェクトを適切に破棄する必要はありません。コードは次のとおりです。何が問題なのか知りたいです。

SLuint32 playerState = 0;

SLresult result = (*pPlayerObject)->GetState(pPlayerObject, &playerState);

return_if_fail(result);

if (playerState == SL_OBJECT_STATE_REALIZED)
{
    (*pPlayerObject)->AbortAsyncOperation(pPlayerObject);
    (*pPlayerObject)->Destroy(pPlayerObject);
}
else
{
    __android_log_print(1, LOG_TAG, "Player object in unexpected state (%d)", playerState);
    return 1002;
}
4

1 に答える 1

2
  1. if (playerState == SL_OBJECT_STATE_REALIZED)

    必要ありません。いつもやってみる。

  2. AbortAsyncOperation必要ありDestroy =>ません。

  3. だから試してみ(*pPlayerObject)->Destroy(pPlayerObject);てください。それだけで十分です。

編集: 私はテストし、解決策を見つけました。Destroy()player から呼び出すことはできませんcallback。" destroy" リストを作成し、別の場所 (メイン スレッドなど) で破棄する必要があります。

于 2014-08-05T03:37:28.783 に答える