坑一
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)
出現(xiàn)這個(gè)錯(cuò)誤是因?yàn)?/strong> 在Activity的onSaveInstanceState方法調(diào)用之后覆享,操作commit方法烹看。
使用場(chǎng)景模擬:已版本升級(jí)功能為例如输。進(jìn)入首頁(yè)Activity濒持,會(huì)去請(qǐng)求檢測(cè)版本升級(jí)接口佑笋,接口還沒(méi)請(qǐng)求成功時(shí),我們按Home鍵退出Activity回到桌面枫振,接口請(qǐng)求成功后喻圃,需要彈出升級(jí)彈框,此時(shí)調(diào)用DialogFragment的show方法就會(huì)報(bào)上面的錯(cuò)蒋得。
解決辦法级及,重寫(xiě)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();
}
}
//通過(guò)反射修改mDismissed额衙、mShownByMe兩個(gè)變量的值是因?yàn)椋创a中show方法會(huì)修改這兩個(gè)值
坑二
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)
出現(xiàn)這個(gè)錯(cuò)誤是因?yàn)?/strong> 同一個(gè)Fragment被add兩次導(dǎo)致的錯(cuò)誤
使用場(chǎng)景模擬:快速點(diǎn)擊按鈕怕吴,彈出分享彈框窍侧,有時(shí)候會(huì)因?yàn)槭謾C(jī)卡頓,導(dǎo)致可以多次點(diǎn)擊转绷,此時(shí)就會(huì)報(bào)上面的錯(cuò)
解決辦法:show方法之前伟件,通過(guò)isAdded 方法判斷,如果已經(jīng)添加就不在添加
完整代碼
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{*;}