DialogFragment 使用遇到的坑
2020-06-29 本文已影响0人
怎么快乐
坑一
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at androidx.fragment.app.FragmentManagerImpl.checkStateLoss(FragmentManagerImpl.java:1536)
at androidx.fragment.app.FragmentManagerImpl.enqueueAction(FragmentManagerImpl.java:1558)
at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:317)
at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:282)
at androidx.fragment.app.DialogFragment.show(DialogFragment.java:155)
出现这个错误是因为 在Activity的onSaveInstanceState方法调用之后,操作commit方法。
使用场景模拟:已版本升级功能为例。进入首页Activity,会去请求检测版本升级接口,接口还没请求成功时,我们按Home键退出Activity回到桌面,接口请求成功后,需要弹出升级弹框,此时调用DialogFragment的show方法就会报上面的错。
解决办法,重写show方法,代码如下:
public void show(@NonNull FragmentManager manager) {
try {
Class<?> c = Class.forName("androidx.fragment.app.DialogFragment");
Field dismissed = c.getDeclaredField("mDismissed");
dismissed.setAccessible(true);
dismissed.set(this, false);
Field shownByMe = c.getDeclaredField("mShownByMe");
shownByMe.setAccessible(true);
shownByMe.set(this, true);
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.add(this, getFragmentTag());
fragmentTransaction.commitAllowingStateLoss();
if (onShowDismissListener != null) onShowDismissListener.show();
} catch (Exception e) {
e.printStackTrace();
}
}
//通过反射修改mDismissed、mShownByMe两个变量的值是因为,源码中show方法会修改这两个值
坑二
java.lang.IllegalStateException: Fragment already added: MyDialogFragment{bfb3730 (d53ee214-34c1-49ff-9c4b-fac59aeb9df3) myDialogFragment}
at androidx.fragment.app.FragmentManagerImpl.addFragment(FragmentManagerImpl.java:1379)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:399)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7551)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
出现这个错误是因为 同一个Fragment被add两次导致的错误
使用场景模拟:快速点击按钮,弹出分享弹框,有时候会因为手机卡顿,导致可以多次点击,此时就会报上面的错
解决办法:show方法之前,通过isAdded 方法判断,如果已经添加就不在添加
完整代码
public void show(@NonNull FragmentManager manager) {
if (this.isAdded()) return;
try {
Class<?> c = Class.forName("androidx.fragment.app.DialogFragment");
Field dismissed = c.getDeclaredField("mDismissed");
dismissed.setAccessible(true);
dismissed.set(this, false);
Field shownByMe = c.getDeclaredField("mShownByMe");
shownByMe.setAccessible(true);
shownByMe.set(this, true);
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.add(this, getFragmentTag());
fragmentTransaction.commitAllowingStateLoss();
if (onShowDismissListener != null) onShowDismissListener.show();
} catch (Exception e) {
e.printStackTrace();
}
}
添加混淆
-keep class androidx.fragment.app.DialogFragment{*;}