44

ユーザーがアクティビティを表示していないときに発生する可能性のあるコミットについて、次のスタックトレースが表示されることがあります(状態が保存された後)。

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)

Androidのソースを見ると、これは完全に理にかなっています。

private void checkStateLoss() {
        if (mStateSaved) {
            throw new IllegalStateException(
                    "Can not perform this action after onSaveInstanceState");
        }
        if (mNoTransactionsBecause != null) {
            throw new IllegalStateException(
                    "Can not perform this action inside of " + mNoTransactionsBecause);
        }
 }

さて、フラグメントが望ましくない状態でコミットされるかどうかをチェックする方法(on(Save / Restore)InstanceStateにクラス変数を格納する以外に)があるかどうか疑問に思います。このようにして、後でトランザクションを格納して作成できます。適切なタイミングでコミットします。

4

8 に答える 8

20

サンプルコードを添付していないため、トランザクションをコミットするときに「間違った」方法を使用していると推測できます。

したがって、 を使用する代わりに、FragmentTransaction.commitAllowingStateLoss()FragmentTransaction.commit()を使用する必要があります 。

また、この google blog postには、この問題 (または API の動作の変更) に関するレポートと回避策があります。

于 2013-03-21T19:17:11.623 に答える
0

RuntimeExceptions (および IllegalStateException もその 1 つ) は、ほとんどの場合、コードが何かを達成しようとした方法が正しくないことを意味します。そのような例外を処理しようとする (たとえば、キャッチすることによって) ことも間違っています。あなたのコードは、Android がこのような例外をスローするように振る舞うべきではありません。

Handlers を使用して、後で処理するメッセージを投稿または送信する場合は、再開状態を終了する前にキューをクリアする必要があります。また、ユーザーがアクティビティから戻る可能性があるため、アクティビティから AsyncTask を開始して onPostExecute でトランザクションをコミットすることはできません。キャンセルして、キャンセルされたかどうかを確認する必要があります。

このような例はたくさんありますが、すべて「一時的な」メモリ リークが原因です。

基本的にあなたのコードは悪く、それを提供しなければ、その方法を知ることは不可能です.

于 2013-03-21T21:23:08.153 に答える
-1

私もこの問題を抱えていたので、どこにも解決策が見つかりませんでした。回避策を試しました。このように機能します。代わりに、ハンドラーからフラグメント トランザクションを作成します。ハンドラーは、2000 ミリ秒の DELAY で呼び出す必要があります。例えば。makeTransaction の呼び出し時

void makeTransaction()
{
  handler.sendEmptyMessageDelayed(0,2000);
}

void actuallyMakeTransaction()
{
 // transaction code
}

Handler handler = new Handler()
{
void handleMessage(Message msg)
{
   actuallyMakeTransaction();
}
}

それは私のために問題を解決しました

于 2013-03-18T06:04:11.830 に答える