在我的活动中,显示自定义DialogFragement。但是当我打开对话框时最小化应用程序时,我收到此错误
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = xxx.xxx.MyActivity$24)
at android.os.Parcel.writeSerializable(Parcel.java:1468)
at android.os.Parcel.writeValue(Parcel.java:1416)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:686)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)
at android.os.Bundle.writeToParcel(Bundle.java:1079)
at android.os.Parcel.writeBundle(Parcel.java:711)
at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:144)
at android.os.Parcel.writeTypedArray(Parcel.java:1254)
at ....
... 23 more
java.io.NotSerializableException: xxx.xxx.MyActivity
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344)
xxxxx
暂时解决这个问题,我已经在对话框片段中设置了这个似乎有效,但我不喜欢这些肮脏的技巧
@Override
public void onPause() {
dismiss();
super.onPause();
}
任何人都可以告诉我这个例外的原因是什么?
自定义DialogFragment的onCreate:
public static MyCustomDialog newInstance(double lat, double lng, MyListener listener) {
MyCustomDialog dialogFragment = new MyCustomDialog();
Bundle bundle = new Bundle();
bundle.putDouble(ARG_LAT, lat);
bundle.putDouble(ARG_LNG, lng);
bundle.putSerializable(ARG_LISTENER, listener);
dialogFragment.setArguments(bundle);
return dialogFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_layout, null, false);
final double lat = getArguments().getDouble(ARG_LAT);
final double lng = getArguments().getDouble(ARG_LNG);
listener = (MyListener) getArguments().getSerializable(ARG_LISTENER);
TextView saveBtn = (TextView) view.findViewById(R.id.save_btn);
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* some processing */
listener.onSave();
}
});
return view;
}
MyListener是一个界面。我一开始以为这可能是问题所在,但即使我没有放入捆绑包,我也会得到同样的错误,所以它必须来自别的东西。
点击按钮内的活动侧:
MyCustomDialog myCustomDialog = MmyCustomDialog.newInstance(lat, lon, listener);
myCustomDialog.show(getSupportFragmentManager(), "tag");
答案 0 :(得分:1)
我在你的代码中看到了这一行:
listener = (MyListener) getArguments().getSerializable(ARG_LISTENER);
如果我猜对了,MyListener
由Activity的内部类或Activity本身实现。无论哪种方式,MyListener都拥有对Activity的引用。请注意,如果您要创建一个匿名内部类,那就是:
MyListener listener = new MyListener() { ... }
它仍然包含对您的活动的引用。
当片段需要被销毁时,参数Bundle存储在片段状态Parcel中。 Android尝试序列化MyListener,但是Activity不是Serializable,它失败了。
通常的模式是在Fragment中声明你的监听器接口:
public class MyFragment extends Fragment {
...
public interface Callbacks {
void doSomething();
}
...
然后,托管Fragment的Activity实现了这个接口:
public class MyActivity extends AppCompatActivity implements MyFragment.Callbacks {
...
@Override
public void doSomething() {
// do your stuff
}
...
在你片段的onAttach
中,你将Fragment的主机转换为你的回调并设置字段。
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (getHost() instanceof Callbacks) {
mCallbacks = (Callbacks) getHost();
} else {
throw new AssertionError("Host does not implement Callbacks!");
}
}
PS在文档中,您可能会看到采用onAttach
的{{1}}方法版本。上述版本已从API 23弃用。在此之前,Fragments只能由Activities托管。现在,Fragments可以由任意对象托管,并在任何Activity
中运行。话虽如此,您可能会在活动中托管您的碎片,并且您的上下文和主机将是相同的。
答案 1 :(得分:0)
尝试使用此方法
dismissAllowingStateLoss();
而不是
dismiss();