美文网首页高级UI
DialogFragment 使用遇到的坑

DialogFragment 使用遇到的坑

作者: 怎么快乐 | 来源:发表于2020-06-29 16:17 被阅读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{*;}
    

    相关文章

      网友评论

        本文标题:DialogFragment 使用遇到的坑

        本文链接:https://www.haomeiwen.com/subject/zzoofktx.html