DialogFragment在Activity执行onSaveInstanceState完成后调用show报BUG的解决方案
来源:互联网 发布:网络运维事迹材料 编辑:程序博客网 时间:2024/05/22 12:24
在开发过程中,发现了这样一个BUG:在用DialogFragment的show(FragmentTransaction transaction,String tag)方法时会报如下BUG:(中间空白为项目代码请忽律)
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1493)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1511)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:638)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:617)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:156)
at com.android.webview.chromium.WebViewContentsClientAdapter.handleJsAlert(W
at org.chromium.android_webview.AwContentsClientBridge.handleJsAlert(A
at org.chromium.ui.base.WindowAndroid.nativeOnVSync(Native Method)
at org.chromium.ui.base.WindowAndroid.access$500(WindowAndroid.java:42)
at org.chromium.ui.base.WindowAndroid$1.onVSync(WindowAndroid.java:121)
at org.chromium.ui.VSyncMonitor.onVSyncCallback(VSyncMonitor.java:129)
at org.chromium.ui.VSyncMonitor.access$400(VSyncMonitor.java:18)
at org.chromium.ui.VSyncMonitor$1.doFrame(VSyncMonitor.java:84)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:672)
at android.view.Choreographer.doFrame(Choreographer.java:605)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:846)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5438)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
从异常可以看出,该问题为宿主Activity在调用了onSaveInstanceState以后,再向其添加DialogFragment的时候就会报此错误。我们知道commitAllowingStateLoss()方法可以解决Activity在调用了onSaveInstanceState以后,报BUG的问题。但是问题来了,DialogFragment的show(FragmentTransaction transaction,String tag)方法源码如下:
public int show(FragmentTransaction transaction, String tag) {
mDismissed = false;
mShownByMe = true;
transaction.add(this, tag);
mViewDestroyed = false;
mBackStackId = transaction.commit();
return mBackStackId;
}
可以看到该方法调用的是commit()(其实这里我们也找到了问题的源头,就在于此)。那么有没有调用commitAllowingStateLoss()的方法呢?答案是我寻找了源码N次,发现没有。怎么办呢?请看如下方法:
ft.add(f,tmp);
ft.commitAllowingStateLoss();
ft为:FragmentTransaction。
这里再提供一个自己的想法,用重写show(FragmentTransaction transaction,String tag)方法,再利用反射修改内部参数,修改此方法,代码如下:
@Override
public int show(FragmentTransaction transaction, String tag) {
try {
Class clazz = Class.forName("android.support.v4.app.DialogFragment");
Field mDismissed = clazz.getDeclaredField("mDismissed");
mDismissed.setAccessible(true);
mDismissed.setBoolean(this,false);
Field mShownByMe = clazz.getDeclaredField("mShownByMe");
mShownByMe.setAccessible(true);
mShownByMe.setBoolean(this,true);
Field mViewDestroyed = clazz.getDeclaredField("mViewDestroyed");
mViewDestroyed.setAccessible(true);
mViewDestroyed.setBoolean(this,false);
transaction.add(this, tag);
return transaction.commitAllowingStateLoss();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return -1;
}
以上2各方法都是经过测试的可用方法。
如有不妥之处请各位大大留言,以待优化,谢谢
- DialogFragment在Activity执行onSaveInstanceState完成后调用show报BUG的解决方案
- DialogFragment 在调用dismiss之后再调用getdialog.show()报错
- SenchaTouch的弹出框,每次都先执行hide后在执行show的解决方案
- 在onActivityResult中弹出DialogFragment的解决方案 activity和fragment
- Activity的onSaveInstanceState调用时机
- Activity的onSaveInstanceState调用时机
- Activity的onSaveInstanceState调用时机的说明
- activity的onSaveInstanceState的调用时机
- activity 中的 onSaveInstanceState方法的调用时机
- activity 中的 onSaveInstanceState方法的调用时机
- activity 中的 onSaveInstanceState方法的调用时机
- Android Activity的onSaveInstanceState() 和 onRestoreInstanceState()调用
- activity 中的 onSaveInstanceState方法的调用时机
- 在onActivityResult中弹出DialogFragment的解决方案
- Fragment 无法在Activity.onSaveInstanceState方法后commit
- 在设置了android:parentActivityName后,点击子Activity返回键,父Activity总会调用OnDestroy()的解决方案
- 在设置了android:parentActivityName后,点击子Activity返回键,父Activity总会调用OnDestroy()的解决方案
- 解决onSaveInstanceState的Bug
- html中三种路径详谈
- 机器学习(三)常见算法优缺点
- 5分钟搞定android混淆
- Spring Security 与 Oauth2 整合 步骤
- Spring Cloud实战(二)-Spring Cloud Eureka
- DialogFragment在Activity执行onSaveInstanceState完成后调用show报BUG的解决方案
- MongoDB的一些基本操作命令(三)————增删改查和语句块操作
- agile_board(Bootstrap)
- Calendar 获取本周周一、周五时间,以及获取当月第一天
- Via composer create Laravel project
- Win7,64位,C++调用Python
- 第17章 创建函数
- java小知识点
- 别逗了,机器人编程=儿童编程