当调用onPause方法时,由于Parcel:无法封送值错误而导致片段崩溃



我已经开发android应用程序一段时间了,但直到最近才进入Fragments,因此我遇到了很多问题,学习如何使用它们。我的应用程序中的一个活动有四个不同的片段,每个片段都向用户显示一个项目列表。每个片段都是首先创建的,只有在被选中时才显示,当另一个选项卡被选中时隐藏。一旦创建了这些片段中的每一个,JSONObjects的ArrayList将作为参数传递给片段,如下所示

            ft = fm.beginTransaction();
            if(currentFragment !=null){
                ft.hide(currentFragment);
            }
            if(whereFragment !=null){
                ft.show(whereFragment);
            }else{
                if(mPlaceList.size()>0){
                Bundle bundle = new Bundle();
                bundle.putSerializable("array", mPlaceList);
                whereFragment = new WhereFragment();
                whereFragment.setArguments(bundle);
                ft.add(R.id.newpost_container,whereFragment, "whereFragment");
                }
            }
            ft.commit();
            currentFragment = whereFragment;

在片段中接收到数组列表,一切正常。

actList = (ArrayList<JSONObject>) getArguments().getSerializable("array");
doingAdapter = new DoingAdapter(getActivity(), actList);
actListView.setAdapter(doingAdapter);

在父活动中有一个启动设备摄像头的按钮。一旦发生这种情况,片段中的onPause方法被调用应用程序崩溃,我在Logcat中得到这个错误

Logcat:

    06-23 17:51:31.190: E/ACRA(29221): com.parspake.anar fatal error : Parcel: unable to marshal value {"type":"act","id":"5327f9827f49143f3a001c76","title":"خونه","actType":"where"}
06-23 17:51:31.190: E/ACRA(29221): java.lang.RuntimeException: Parcel: unable to marshal value {"type":"act","id":"5327f9827f49143f3a001c76","title":"خونه","actType":"where"}
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeValue(Parcel.java:1235)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeList(Parcel.java:622)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeValue(Parcel.java:1195)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeMapInternal(Parcel.java:591)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Bundle.writeToParcel(Bundle.java:1619)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeBundle(Parcel.java:605)
06-23 17:51:31.190: E/ACRA(29221):  at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:132)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeTypedArray(Parcel.java:1102)
06-23 17:51:31.190: E/ACRA(29221):  at android.support.v4.app.FragmentManagerState.writeToParcel(FragmentManager.java:368)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeParcelable(Parcel.java:1254)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeValue(Parcel.java:1173)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeMapInternal(Parcel.java:591)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Bundle.writeToParcel(Bundle.java:1619)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Parcel.writeBundle(Parcel.java:605)
06-23 17:51:31.190: E/ACRA(29221):  at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2096)
06-23 17:51:31.190: E/ACRA(29221):  at android.app.ActivityThread$StopInfo.run(ActivityThread.java:2918)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Handler.handleCallback(Handler.java:615)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Handler.dispatchMessage(Handler.java:92)
06-23 17:51:31.190: E/ACRA(29221):  at android.os.Looper.loop(Looper.java:137)
06-23 17:51:31.190: E/ACRA(29221):  at android.app.ActivityThread.main(ActivityThread.java:4827)
06-23 17:51:31.190: E/ACRA(29221):  at java.lang.reflect.Method.invokeNative(Native Method)
06-23 17:51:31.190: E/ACRA(29221):  at java.lang.reflect.Method.invoke(Method.java:511)
06-23 17:51:31.190: E/ACRA(29221):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
06-23 17:51:31.190: E/ACRA(29221):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
06-23 17:51:31.190: E/ACRA(29221):  at dalvik.system.NativeStart.main(Native Method)

我一直在寻找周围的stackoverflow,我确实看到一些问题类似于我的问题,但我似乎不能采取任何可以帮助我与我的情况。我确实得到了问题的要点与片段试图保存其状态,不能序列化我的json对象,但如果有人能帮助我工作无论是Serializable或Parcelable接口来解决我的问题,那将是伟大的。此外,我已经在片段和活动中实现了Serializable,因为它已被其他人建议。

如果你已经得到了你需要的数据,那么就从bundle中删除数据。

// get your data
Bundle bundle = getArguments();
JSONObject myData = (JSONObject) bundle.getSerializable("myData");
// remove it
getArguments().remove("myData");

我设法找到了一个方法,这可能不是最标准的做事方式,但它实际上解决了我的问题,并可能在某种程度上帮助别人。

我所做的不是将从API接收到的JSONArray转换为JSON数组列表,然后将其发送到片段,而是将JSON数组转换为字符串,并将其与bundle一起发送。

                ft = fm.beginTransaction();
                if(currentFragment !=null){
                    ft.hide(currentFragment);
                }
                if(doingFragment !=null){
                    ft.show(doingFragment);
                }else{
                    if(mActList.size()>0){
                    Bundle bundle = new Bundle();
                    bundle.putString("array", jArrayWhat.toString());
                    doingFragment = new DoingFragment();
                    doingFragment.setArguments(bundle);
                    ft.add(R.id.newpost_container,doingFragment, "doingFragment");
                    }
                }
                ft.commit();

在片段中,我接收了bundle并将字符串转换为JSONArray。

    jsonActList = new JSONArray(getArguments().getString("array"));

然后遍历JSONArray并将其转换为JSONObject ArrayList。为了在使用片段后保留对my列表所做的更改,我将ArrayList转换回JSONArray并保存它。

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    JSONArray jArray = new JSONArray(Arrays.asList(actList));
    outState.putString("jsonArray", jArray.toString());
}

现在状态已经保存,可以很容易地在onCreateView方法中恢复,如下所示

 if ((savedInstanceState != null)
                   && (savedInstanceState.getSerializable("jsonArray") != null)) {
             jsonActList = new JSONArray(savedInstanceState.getString("jsonArray"));
             positionList = (ArrayList<String>) savedInstanceState.getSerializable("positionList");
    }

这样我就不必处理让JSONObjects可序列化或可Parcelable的问题

最新更新