我的活动使用ACTION_IMAGE_CAPTURE意图调用相机。如果相机活动成功返回,我在onActivityResult回调中设置了一个标志,并根据标志的值我在onResume中启动一个片段,为捕获的图像添加标题。这似乎工作正常。
我刚从“狂野”中得到一个堆栈跟踪抱怨我在调用onSaveInstanceState后尝试提交片段事务。但我正在使用onResume方法进行提交!为什么android会抱怨这个?我的AndroidManifest.xml中设置了 android:configChanges =“orientation | keyboardHidden | keyboard | screenSize”,因此方向更改不应触发此....
这发生在运行4.0.4的三星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)
感谢任何帮助或智慧。
答案 0 :(得分:55)
我认为我知道答案 - 我正在使用v4兼容库中的FragmentActivity,所以我需要在onResumeFragments而不是onResume中执行我的片段事务。有人可以证实吗?
答案 1 :(得分:13)
您可以使用方法commitAllowingStateLoss()
但请注意,您可能会失去活动状态 正如你在谷歌android reference中看到的那样 用以下方式解释两者之间的差异
与commit()类似,但允许在保存活动状态后执行提交。这很危险,因为如果活动需要稍后从其状态恢复,则提交可能会丢失,因此这应仅用于UI状态可以在用户上意外更改的情况。
根据我的经验,它可能导致addToBackStack
方法有时无法工作,因此您需要在片段上手动添加它
当然,状态不会被保存(文本框文本分机)
答案 2 :(得分:3)
这对我有用......我自己发现了......希望它对你有帮助!
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();
}
}
答案 3 :(得分: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();
}
}
并调用直接进入onResume或onResumeFragments的片段事务到我的自定义 onFragmentAttached 方法,该方法由不可见状态片段调用。我根本不使用onResumeFragments,也不在onResume中发出任何片段事务。
所以,总结一下。如果您正在使用支持库和片段,几乎忘记onResume,忘记onResumeFragments并基于上述解决方法实现您自己的“onResume”。 这有点荒谬。
我无法确认。我有完全一样的问题。即使我在onResumeFragments中发出片段事务。 这曾经像我在这里发布的那样工作:IllegalStateException - Fragment support library。
似乎错误仅发生在4.0.3和4.0.4上。但它并不总是发生在我的模拟器中。
我正在使用支持lib rev。 10和API 16。 我在onResumeFragments中调用DialogFragment.show并不断从一些随机用户那里得到这个荒谬的例外。我无法在本地重现它。
答案 4 :(得分:1)
我首先使用支持v4库开发针对android 2.2(SDK 8)的应用程序,当我开始使用4.2(SDK 17)时,我的片段也遇到了同样的麻烦。但是将我的Manifest改为android:minSdkVersion =“8”android:targetSdkVersion =“17”,解决了我的问题。也许这也让你感到高兴。
答案 5 :(得分:1)
当我试图在onActivityForResult()方法中显示片段时,我总是得到这个,所以接下来是问题:
我接下来做了什么:
答案 6 :(得分:0)
@Override
protected void onSaveInstanceState(Bundle outState) {
//No call for super(). Bug on API Level > 11.
}