简体   繁体   English

当打开dialogFragment并调用onPause()时,活动崩溃

[英]Activity crashes when dialogFragment is opened and onPause() is called

I made a custom dialog (extends DialogFragment) that appears in several activities. 我创建了一个自定义对话框(扩展了DialogFragment),该对话框出现在多个活动中。

If the activity comes to foreground while the dialog is opened, I get the following error: 如果在打开对话框时活动进入前台,则会出现以下错误:

 FATAL EXCEPTION: main

Process: package.name, PID: 11137

java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = myFragmentOrActivityWhereOccuredTheError)
...
 Caused by: java.io.NotSerializableException: android.support.v7.widget.AppCompatButton

Depends on the activity or fragment, "Caused by" changes, because the problem is not there, is the DialogFragment (without showing the dialog fragments everything works) 取决于活动或片段,“原因是”的更改(因为问题不存在)是DialogFragment (未显示对话框片段一切正常)

There is a solution: calling dismiss() before the activity goes to foreground. 有一个解决方案:在活动进入前台之前调用dismiss()。 But I have to write a lot of code because I have to show it again in case the dialog was opened before the activity came to foreground and also is not simple to handle that with the complexity of the activies. 但是我必须编写大量代码,因为如果在活动进入前台之前打开了对话框,则必须再次显示它,并且由于活动的复杂性也不容易处理。

What I need: Solve the problem without dismissing the dialog. 我需要什么:在不关闭对话框的情况下解决问题。 I think I have an error on my DialogFragment Class. 我想我的DialogFragment类有错误。 So... this is the code of my class: 所以...这是我班上的代码:

public class RequestDialog extends DialogFragment {

    public static String DIALOG_INTERFACE = "dialogInterface";
    public static String REQUIERE_ACTIVACION_MANUAL = "activationMode";
    public static String SCHEME = "package";

    public interface MyDialogInterface extends Serializable {
        void onClickContinuarEvent(int permisoRequerido);
        void onClickCancelarEvent(int permisoRequerido);
    }

    private MyDialogInterface callbackListener;

    /**
     * dialogInterface - instance of MyDialogInterface which will handle
     * callback events
     */
    public static RequestDialog getInstance(MyDialogInterface dialogInterface, boolean activationMode) {
        RequestDialog fragmentDialog = new RequestDialog();

        // set fragment arguments
        Bundle args = new Bundle();
        args.putSerializable(DIALOG_INTERFACE, dialogInterface);
        args.putBoolean(REQUIERE_ACTIVACION_MANUAL, activationMode);

        fragmentDialog.setArguments(args);

        return fragmentDialog;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Bundle extras = getArguments();
        callbackListener = (MyDialogInterface) extras.getSerializable(DIALOG_INTERFACE);
        final boolean activationMode = extras.getBoolean(REQUIERE_ACTIVACION_MANUAL);

        View view = View.inflate(getActivity(), R.layout.rationale_dialog, null);

        TextView texDetalle = view.findViewById(R.id.texDetalle);
        TextView texContinuar = view.findViewById(R.id.texContinuar);
        TextView texCancelar = view.findViewById(R.id.texCancelar);
        ImageView imgCabecera = view.findViewById(R.id.imgCabecera);


        imgCabecera.setBackground(ContextCompat.getDrawable(getActivity(), R.drawable.ic_folder));
        Typeface typeFace = Typeface.createFromAsset(getActivity().getAssets(), "fonts/MyFont.ttf");
        texDetalle.setTypeface(typeFace);

        final AlertDialog.Builder requestDialogBuilder = new AlertDialog.Builder(getActivity(), R.style.NarrowDialog);
        requestDialogBuilder.setView(view);

        final AlertDialog dialog = requestDialogBuilder.create();
        dialog.setContentView(view);
        final Window window = dialog.getWindow();
        if(window != null){
            window.setLayout(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
            window.setGravity(Gravity.CENTER);

            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
            Display display = getActivity().getWindowManager().getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            dialog.getWindow().setLayout(size.x*70/100, WindowManager.LayoutParams.WRAP_CONTENT);

            texContinuar.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(activationMode){
                        goToPreferencesSystem();
                        callbackListener.onClickCancelarEvent(1);
                    }
                    else{
                        callbackListener.onClickContinuarEvent(0);
                    }
                    dialog.dismiss();
                }
            });

            texCancelar.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    callbackListener.onClickCancelarEvent(2);
                    dialog.dismiss();
                }
            });
        }
        setCancelable(false);
        return dialog;
    }
}

As you can see, there is two callback that I have to handle in the activies. 如您所见,在活动中必须处理两个回调。

So... Do you have any idea hoy to solve this problem? 所以...您有解决这个问题的想法吗?

Thanks! 谢谢!

EDIT: 编辑:

In any activity I have to implement the dialog like this: 在任何活动中,我都必须像这样实现对话框:

MyActivity implements RequestDialog.MyDialogInterface

And then override the callbacks: 然后覆盖回调:

@Override
public void onClickContinuarEvent(int request) {
}

@Override
public void onClickCancelarEvent(int permisoRequerido) {}

You really should not be making anything Serializable that should die when the lifecycle of a fragment/activity die. 当片段/活动的生命周期终止时,您实际上不应该进行任何应终止的可序列化。 For this solution, remove the interface on the getInstance(). 对于此解决方案,请删除getInstance()上的接口。 You should not pass interfaces via fragment creation. 您不应通过片段创建来传递接口。 You should create a setter for the interface. 您应该为接口创建一个setter。 I don't have nearly enough information to solve the issue but, I believe this may be the solution. 我没有足够的信息来解决问题,但是,我相信这可能是解决方案。 Let me know if it works, so I can delete if it it doesn't. 让我知道它是否有效,所以如果它无效则可以删除。

Dialog 对话

public class RequestDialog extends DialogFragment {
    private MyDialogInterface callbackListener;

    public interface MyDialogInterface {
        void onClickContinuarEvent(int permisoRequerido);

        void onClickCancelarEvent(int permisoRequerido);
    }

    public void setCallbackListener(MyDialogInterface callbackListener) {
        this.callbackListener = callbackListener;
    }
    public static RequestDialog getInstance( boolean activationMode) {
        RequestDialog fragmentDialog = new RequestDialog();
        Bundle args = new Bundle();
        args.putBoolean(REQUIERE_ACTIVACION_MANUAL, activationMode);
        fragmentDialog.setArguments(args);
        return fragmentDialog;
    }
}

Create Dialog 创建对话框

RequestDialog requestDialog = RequestDialog.getInstance(true);
requestDialog.setCallbackListener(new RequestDialog.MyDialogInterface() {
    @Override
    public void onClickContinuarEvent(int permisoRequerido) {

    }

    @Override
    public void onClickCancelarEvent(int permisoRequerido) {

    }
});
requestDialog.show(getSupportFragmentManager(), "REQUEST_DIALOG");

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

相关问题 当其他活动打开时,从未调用过OnPause()和onDestroy() - OnPause() and also onDestroy() never called when other activity opened 在片段之间切换时会调用Activity onpause吗 - Will Activity onpause be called when switching between fragments Android 活动生命周期 - 何时调用“onPause”? - Android Activity LifeCycle - when 'onPause' is called? onPause 是否保证在 Activity 不再运行时调用? - Is onPause guaranteed to be called when an Activity is no longer running? 在Activity上调用onPause时,数据会发生什么 - What happens to data when onPause is called on Activity 在模拟器中重新启动活动时未调用OnPause() - OnPause() not called when relaunch activity in emulator 调用startActivity()时DialogFragment崩溃活动 - DialogFragment crashes Activity when calling startActivity() 当 DialogFragment 以屏幕旋转变化打开时,Observer 会被多次调用 - Observer is called multiple times when DialogFragment is opened with screen rotation changes 从Activity或Fragment打开的DialogFragment? - DialogFragment opened from Activity or Fragment? 最小化并打开对话框时,活动崩溃 - Activity crashes when minimized and a dialog is opened
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM