1. ホーム
  2. android

"結果を出すのに失敗した" - onActivityForResult

2023-09-08 23:22:27

質問

私は LoginActivity (ユーザがログイン) である。これは基本的に、それ自身の Activity で、ダイアログのようなテーマを持っています(ダイアログのように見えるように)。の上に表示されます。 SherlockFragmentActivity . 私が欲しいのは、次のようなものです。 ログインに成功した場合、2つの FragmentTransaction でビューを更新することです。以下はそのコードです。

LoginActivity で、ログインに成功した場合。

setResult(1, new Intent());

SherlockFragmentActivity :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == 1) {
        LoggedStatus = PrefActivity.getUserLoggedInStatus(this);
        FragmentTransaction t = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction();
        SherlockListFragment mFrag = new MasterFragment();
        t.replace(R.id.menu_frame, mFrag);
        t.commit();

        // Set up Main Screen
        FragmentTransaction t2 = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction();
        SherlockListFragment mainFrag = new FeaturedFragment();
        t2.replace(R.id.main_frag, mainFrag);
        t2.commit();
    }
}

最初のコミットでクラッシュし、このLogCatが表示されます。

E/AndroidRuntime(32072): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
E/AndroidRuntime(32072):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
E/AndroidRuntime(32072):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
E/AndroidRuntime(32072):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
E/AndroidRuntime(32072):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
E/AndroidRuntime(32072):    at com.kickinglettuce.rate_this.MainFragmentActivity.onActivityResult(MainFragmentActivity.java:243)
E/AndroidRuntime(32072):    at android.app.Activity.dispatchActivityResult(Activity.java:5293)
E/AndroidRuntime(32072):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3315)

どのように解決するのですか?

まず最初に、私の ブログ記事 を参照してください (この例外が発生する理由と、それを防ぐためにできることについて書かれています)。

呼び出し commitAllowingStateLoss() を呼び出すことは、修正というよりもハックに近いです。ステートロスは悪いことであり、何としても避けるべきことです。その時点で onActivityResult() が呼び出された時点では、アクティビティやフラグメントの状態はまだ復元されていない可能性があります。これは非常に重要なバグであり、対処しなければなりません! (このバグが発生するのは Activity がシステムによって強制終了された後に戻ってきたときにのみ発生することに注意してください。これは、デバイスのメモリ量に依存しますが、時には稀なことです。)

トランザクションを onPostResume() に移動させてみてください(ただし onPostResume() は常に onResume()onResume() が呼び出されるのは常に onActivityResult() ):

private boolean mReturningWithResult = false;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mReturningWithResult = true;
}

@Override
protected void onPostResume() {
    super.onPostResume();
    if (mReturningWithResult) {
        // Commit your transactions here.
    }
    // Reset the boolean flag back to false for next time.
    mReturningWithResult = false;
}

これは少し奇妙に思えるかもしれませんが、このようなことをするのは、あなたの FragmentTransaction が常にコミットされるようにするためです。 の後に の後にコミットされます。 Activity の状態が元の状態に戻された ( onPostResume() が呼び出された後であることが保証されています。 Activity の状態が復元された後に呼び出されることが保証されています)。