30

私のアクティビティは、ACTION_IMAGE_CAPTUREインテントを使用してカメラを呼び出します。カメラアクティビティが正常に戻った場合は、onActivityResultコールバックにフラグを設定し、フラグの値に基づいてonResumeでフラグメントを開始し、キャプチャされた画像にキャプションを追加します。これは問題なく機能しているようです。

onSaveInstanceStateが呼び出された後、フラグメントトランザクションをコミットしようとしているという「ワイルド」からスタックトレースを取得しました。しかし、私はonResumeメソッドでコミットを行っています!なぜAndroidはこれについて不平を言うのでしょうか?AndroidManifest.xmlにandroid:configChanges = "orientation |keyboardHidden |keyboard | screenSize"が設定されているので、向きを変更してもこれがトリガーされないはずです。

これは、4.0.4を実行しているSamsung Galaxy S3(SGH-i747)で発生しました

スタックは次のとおりです。

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314)
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1325)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:532)
    at com.Familiar.Android.FamiliarAppV1.AddPhotosActivity2.performFragmentTransition(AddPhotosActivity2.java:278)
    at com.Familiar.Android.FamiliarAppV1.AddPhotosActivity2.switchToCaptionsFragment(AddPhotosActivity2.java:438)
    at com.Familiar.Android.FamiliarAppV1.AddPhotosActivity2.onResume(AddPhotosActivity2.java:167)
    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1158)
    at android.app.Activity.performResume(Activity.java:4544)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2448)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2486)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1187)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4514)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
    at dalvik.system.NativeStart.main(Native Method)

どんな助けや知恵も大歓迎です。

4

7 に答える 7

56

私は答えを知っていると思います-私はv4互換性ライブラリのFragmentActivityを使用しているので、onResumeではなくonResumeFragmentsでフラグメントトランザクションを実行する必要があります。誰かが確認できますか?

于 2012-09-16T19:35:06.830 に答える
15

あなたは方法を使うことができます commitAllowingStateLoss()

ただし、次のように2つの違いを説明しているGoogleのAndroidリファレンスで確認できるように、アクティビティの状態が失われる可能性があることに注意してください。

commit()と同様ですが、アクティビティの状態が保存された後にコミットを実行できます。アクティビティを後でその状態から復元する必要がある場合、コミットが失われる可能性があるため、これは危険です。したがって、これは、ユーザーのUI状態が予期せず変更されても問題がない場合にのみ使用する必要があります。

私の経験から、addToBackStackメソッドが機能しない場合があるため、フラグメントに手動で追加する必要があります。もちろん、状態は保存されません(テキストボックステキスト内線)。

于 2013-06-15T16:56:43.997 に答える
4

これは私のために働いた...私自身でこれを見つけた...それがあなたを助けることを願っています!

1)グローバルな「静的」FragmentManager/FragmentTransactionがありません。

2)onCreate、常にFragmentManagerを再度初期化します!

以下のサンプル:-

public abstract class FragmentController extends AnotherActivity{
protected FragmentManager fragmentManager;
protected FragmentTransaction fragmentTransaction;
protected Bundle mSavedInstanceState;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mSavedInstanceState = savedInstanceState;
    setDefaultFragments();
}

protected void setDefaultFragments() {
    fragmentManager = getSupportFragmentManager();
    //check if on orientation change.. do not re-add fragments!
    if(mSavedInstanceState == null) {
        //instantiate the fragment manager

        fragmentTransaction = fragmentManager.beginTransaction();

        //the navigation fragments
        NavigationFragment navFrag = new NavigationFragment();
        ToolbarFragment toolFrag = new ToolbarFragment();

        fragmentTransaction.add(R.id.NavLayout, navFrag, "NavFrag");
        fragmentTransaction.add(R.id.ToolbarLayout, toolFrag, "ToolFrag");
        fragmentTransaction.commitAllowingStateLoss();

        //add own fragment to the nav (abstract method)
        setOwnFragment();
    }
}
于 2013-04-19T09:18:08.460 に答える
2

更新ここで説明と解決策を見つけたと思います: http ://code.google.com/p/android/issues/detail ?id = 23096#c4そこに投稿されたEmpty Fragment Workaroundを実装し、IllegalStateExceptionがなくなったので遠い。

このように、アクティビティに非表示の状態フラグメントを追加します。

@Override
protected void onCreate(final Bundle args) {
    ...
    if (args == null) {
        final FragmentManager fm = this.getSupportFragmentManager();
        final FragmentTransaction ft = fm.beginTransaction();
        final Fragment emptyFragmentWithCallback = new EmptyFragmentWithCallbackOnResume();
        ft.add(emptyFragmentWithCallback, EmptyFragmentWithCallbackOnResume.TAG);
        ft.commit();
    }

次のコードは、上記のリンクから取得したものです。

public class EmptyFragmentWithCallbackOnResume extends Fragment {
OnFragmentAttachedListener mListener = null;

@Override
public void onAttach(SupportActivity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentAttachedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement OnFragmentAttachedListener");
    }
}

@Override
public void onResume() {
    super.onResume();
    if (mListener != null) {
        mListener.OnFragmentAttached();
    }
}

public interface OnFragmentAttachedListener {
    public void OnFragmentAttached();
}
}

そして、非表示状態のフラグメントによって呼び出されるカスタムonFragmentAttachedメソッドに直観的にonResumeまたはonResumeFragmentsに入るフラグメントトランザクションを呼び出します。私はonResumeFragmentsをまったく使用せず、onResumeでフラグメントトランザクションを発行しません。

だから、それを要約すると。サポートライブラリとフラグメントを使用している場合は、onResumeをほとんど忘れ、onResumeFragmentsを忘れて、上記の回避策に基づいて独自の「onResume」を実装してください。これはややばかげています。


確認できません。私はまったく同じ問題を抱えています。onResumeFragmentsでフラグメントトランザクションを発行していますが。これは、私がここに投稿したときに機能していました:IllegalStateException-フラグメントサポートライブラリ

エラーは4.0.3と4.0.4でのみ発生するようです。ただし、常に発生するわけではなく、エミュレータでも発生しません。

私はsupportlibrevを使用しています。10およびAPI16。onResumeFragmentsでDialogFragment.showを呼び出し、一部のランダムユーザーからこのばかげた例外を継続的に取得します。ローカルで再現することはできません。

于 2012-10-01T21:39:55.573 に答える
2

onActivityForResult()メソッドでフラグメントを表示しようとすると、常にこれが発生していたため、次の問題が発生しました。

  1. My Activityは一時停止および停止されます。つまり、onSaveInstanceState()がすでに呼び出されています(Honeycomb以前のデバイスとHoneycomb後のデバイスの両方)。
  2. 結果が出た場合は、フラグメントを表示/非表示にするトランザクションを実行しました。これにより、このIllegalStateExceptionが発生します。

私が作ったのは次です:

  1. 必要なアクションが実行されたかどうかを判断するための付加価値(たとえば、camereから写真を撮る-isPhotoTaken)-必要なトランザクションの量に応じて、ブール値または整数値にすることができます。
  2. オーバーライドされたonResumeFragments()メソッドで、値を確認し、フラグメントトランザクションを実行した後に必要になりました。この場合、onResumeFragments()メソッドで状態が返されたため、onSaveInstanceStateの後にcommit()は実行されませんでした。
于 2014-09-06T12:09:38.633 に答える
1

最初に、サポートv4ライブラリを使用してAndroid 2.2(SDK 8)を対象としたアプリを開発しましたが、4.2(SDK 17)で使用を開始すると、フラグメントでも同じ問題が発生しました。しかし、マニフェストをandroid:minSdkVersion = "8" android:targetSdkVersion = "17"に変更すると、問題が解決しました。多分これもあなたを喜ばせます。

于 2012-12-16T18:24:20.743 に答える
0

これをアクティビティに追加します。

 @Override
    protected void onSaveInstanceState(Bundle outState) {
        //No call for super(). Bug on API Level > 11.
    }
于 2019-01-30T06:48:47.927 に答える