简体   繁体   English

Android java.lang.IllegalStateException:已添加片段

[英]Android java.lang.IllegalStateException: Fragment already added

I'm getting a loading object waiting for a request from the webservice.我正在获取一个正在等待来自网络服务的请求的加载对象。 But sometimes this object causes my application to end.但有时这个对象会导致我的应用程序结束。 I couldn't detect exactly what the error involved.我无法确切地检测到所涉及的错误。

In order to prevent this error, I called the object "dismiss" and "cancel" while passing the activity, but this did not work.为了防止这个错误,我在传递活动时调用了对象“dismiss”和“cancel”,但这不起作用。 I then assigned a value of "null" which didn't work either.然后我分配了一个“null”值,它也不起作用。 I didn't work again because I thought I was dealing with Tag.我没有再工作,因为我以为我在和 Tag 打交道。

My error code;我的错误代码;

2019-03-27 11:51:20.502 29685-29685/com.xxxx.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.xxxx.app, PID: 29685
    java.lang.IllegalStateException: Fragment already added: DelayedProgressDialog{d8bd442 #1 Delaleyed}
        at androidx.fragment.app.FragmentManagerImpl.addFragment(FragmentManager.java:1916)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:765)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
        at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:6981)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

My using progress dialog class;我的使用进度对话框类;

    public class DelayedProgressDialog extends DialogFragment {
    private static final int DELAY_MILLISECOND = 450;
    private static final int MINIMUM_SHOW_DURATION_MILLISECOND = 300;
    private static final int PROGRESS_CONTENT_SIZE_DP = 80;

    private ProgressBar mProgressBar;
    private boolean startedShowing;
    private long mStartMillisecond;
    private long mStopMillisecond;

    private FragmentManager fragmentManager;
    private String tag;
    private Handler showHandler;

    // default constructor. Needed so rotation doesn't crash
    public DelayedProgressDialog() {
        super();
    }

    @NonNull
    @SuppressLint("InflateParams")
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();

        builder.setView(inflater.inflate(R.layout.dialog_progress, null));
        return builder.create();
    }

    @Override
    public void onStart() {
        super.onStart();
        mProgressBar = getDialog().findViewById(R.id.progress);

        if (getDialog().getWindow() != null) {
            int px = (int) (PROGRESS_CONTENT_SIZE_DP * getResources().getDisplayMetrics().density);
            getDialog().getWindow().setLayout(px, px);
            getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }
    }

    @Override
    public void show(FragmentManager fm, String tag) {
        if (isAdded())
            return;

        this.fragmentManager = fm;
        this.tag = tag;
        mStartMillisecond = System.currentTimeMillis();
        startedShowing = false;
        mStopMillisecond = Long.MAX_VALUE;

        showHandler = new Handler();
        showHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                // only show if not already cancelled
                if (mStopMillisecond > System.currentTimeMillis())
                    showDialogAfterDelay();
            }
        }, DELAY_MILLISECOND);
    }

    private void showDialogAfterDelay() {
        startedShowing = true;

        DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag(tag);
        if (dialogFragment != null) {
            fragmentManager.beginTransaction().show(dialogFragment).commitAllowingStateLoss();
        } else {
            FragmentTransaction ft = fragmentManager.beginTransaction();
            ft.add(this, tag);
            ft.commitAllowingStateLoss();
        }
    }

    public void cancel() {
        if(showHandler == null)
            return;

        mStopMillisecond = System.currentTimeMillis();
        showHandler.removeCallbacksAndMessages(null);

        if (startedShowing) {
            if (mProgressBar != null) {
                cancelWhenShowing();
            } else {
                cancelWhenNotShowing();
            }
        } else
            dismiss();
    }

    private void cancelWhenShowing() {
        if (mStopMillisecond < mStartMillisecond + DELAY_MILLISECOND + MINIMUM_SHOW_DURATION_MILLISECOND) {
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    dismiss();
                }
            }, MINIMUM_SHOW_DURATION_MILLISECOND);
        } else {
            dismiss();
        }
    }

    private void cancelWhenNotShowing() {
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                dismiss();
            }
        }, DELAY_MILLISECOND);
    }

    @Override
    public void dismiss() {
        FragmentTransaction ft = fragmentManager.beginTransaction();
        ft.remove(this);
        ft.commitAllowingStateLoss();
    }
}

I finally found the solution.我终于找到了解决方案。 I was looking for tags with "findFragmentByTag" in my "showDialogAfterDelay" function.我在“showDialogAfterDelay”函数中寻找带有“findFragmentByTag”的标签。 But this never came true.但这从未成真。 I couldn't determine if it was "Added".我无法确定它是否是“已添加”。 The piece of code I use to solve this;我用来解决这个问题的一段代码;

        fragmentManager.executePendingTransactions();

Just change private void showDialogAfterDelay() .只需更改private void showDialogAfterDelay() You have to check if the dialog is already added;您必须检查对话框是否已添加;

Add : if(dialogFragment != null && dialogFragment.isAdded()) { return; }添加: if(dialogFragment != null && dialogFragment.isAdded()) { return; } if(dialogFragment != null && dialogFragment.isAdded()) { return; }

That code should run before you are trying to show dialog.该代码应该在您尝试显示对话框之前运行。

You need to check if the dialogFragment is already added;您需要检查是否已经添加了dialogFragment If dialogFragment not added then show it:如果没有添加dialogFragment则显示它:

if (fragmentManager.findFragmentByTag("progress_dialog") == null) 
    dialogFragment.show(getSupportFragmentManager(), "progress_dialog");

You can do a quick check in your code before open the Fragment:您可以在打开 Fragment 之前快速检查您的代码:

    if(myFragment.isAdded()){
       return;
    }
// else continue with code

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.IllegalStateException:片段已添加 - java.lang.IllegalStateException: Fragment already added java.lang.IllegalStateException:片段已添加 - java.lang.IllegalStateException: Fragment already added java.lang.IllegalStateException:已添加片段: - java.lang.IllegalStateException: Fragment already added: java.lang.IllegalStateException:已添加片段: - java.lang.IllegalStateException: Fragment already added : java.lang.IllegalStateException:已添加片段:带有 FragmentStatePagerAdapter 的 Fragment1 - java.lang.IllegalStateException: Fragment already added: Fragment1 with FragmentStatePagerAdapter java.lang.IllegalStateException:片段已添加:NamedFragment - java.lang.IllegalStateException: Fragment already added: NamedFragment java.lang.IllegalStateException:即使在.i⚓()之后,也已经添加了片段 - java.lang.IllegalStateException: Fragment already added even after .isAdded() 引起:java.lang.IllegalStateException: Fragment already added - Caused by: java.lang.IllegalStateException: Fragment already added java.lang.IllegalStateException:Fragment 已经为 BottomSheetDialogFragment 添加了异常 - java.lang.IllegalStateException: Fragment already added exception for BottomSheetDialogFragment java.lang.IllegalStateException:已添加片段:MovieFragment - java.lang.IllegalStateException: Fragment already added: MovieFragment
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM