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