[英]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.