2016-11-18 86 views
0

在我的活动中,显示一个Custom 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

它看起来像试图保存包中的某些内容以便稍后重新启动活动。如果在对话框打开的情况下更改方向,它是否也会崩溃? – Nemesis

+0

是的,它也崩溃 – Johny19

回答

0

尝试使用这种方法

dismissAllowingStateLoss(); 

代替

dismiss(); 
1

我看到这行代码:

listener = (MyListener) getArguments().getSerializable(ARG_LISTENER); 

如果我猜对了,MyListener是由您的Activity的内部类或活动本身实现的。无论哪种方式,MyListener都会保存对Activity的引用。请注意,如果你正在创建一个匿名内部类,那就是:

MyListener listener = new MyListener() { ... } 

它仍然持有对您的活动的引用。

当片段需要被销毁时,参数Bundle被存储在片段状态Parcel中。 Android尝试序列化MyListener,但Activity不是可序列化的,并且失败。

通常的模式是声明监听器接口您的片段:

public class MyFragment extends Fragment { 
    ... 
    public interface Callbacks { 
     void doSomething(); 
    } 
    ... 

然后承载碎片的活动实现了这个接口:

public class MyActivity extends AppCompatActivity implements MyFragment.Callbacks { 
    ... 
    @Override 
    public void doSomething() { 
     // do your stuff 
    } 
    ... 

在你片段的onAttach你投的片段的主机到您的回调并设置字段。

@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方法的版本服用Activity。上述版本已从API 23弃用。在此之前,Fragments只能由活动托管。现在,碎片可以由任意对象托管并在任何Context中运行。话虽如此,你可能会将你的碎片存放在活动中,而你的上下文和主机将是相同的。

+0

“如果我猜对了,MyListener是你的活动的内部类” 不,它不是。它是一个新文件中的单独界面。起初它是在我认为是问题的MyCustomDialog中。但问题仍然存在后,我把它移动到一个新的文件 我写过的问题,即使没有MyListener它崩溃以及 – Johny19

+1

对不起,错误的措辞。我的意思是你的Activity的内部类实现你的接口,或者你的Activity实现你的接口。我更新了答案以澄清这一点。 –

+0

但是你在哪里看到我正在使用片段?我在这里谈论一个DialogFragment。 – Johny19

相关问题