碎片与Parcel崩溃:调用onPause方法时无法编组值错误

Nam*_*imi 10 android serializable android-fragments jsonobject

我一直在开发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;
Run Code Online (Sandbox Code Playgroud)

片段中收到了arraylist,一切正常.

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

父活动中有一个按钮可启动设备摄像头.一旦发生这种情况并且片段中的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)
Run Code Online (Sandbox Code Playgroud)

我一直在浏览stackoverflow,我确实看到一些类似于我的问题的问题,但是我似乎无法从任何可以帮助我处理我的情况的任何东西中取出任何东西.我确实得到了问题的要点,片段试图保存其状态并且无法序列化我的json对象但是如果有人可以帮助我使用Serializable或Parcelable接口来解决我的问题,那将是很好的,那将是大.此外,我已经在片段和活动中实现了Serializable,因为其他人已经建议过.

Lee*_*min 29

如果您已经获得了所需的数据,那么只需从bundle中删除数据即可.

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

// remove it
getArguments().remove("myData");
Run Code Online (Sandbox Code Playgroud)

  • 我现在很确定通过从我的包中清除每个值我不再收到编组错误,但有人可以解释为什么必须删除每个值,即使从读取后再也不会再触及该包?非常好奇! (5认同)

Nam*_*imi 4

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

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

                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();
Run Code Online (Sandbox Code Playgroud)

在片段中,我收到了捆绑包并将字符串转换为 JSONArray。

    jsonActList = new JSONArray(getArguments().getString("array"));
Run Code Online (Sandbox Code Playgroud)

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

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

现在状态已保存,可以在 onCreateView 方法中轻松恢复,如下所示

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

这样我就不必处理使 JSONObjects 可序列化或可解析的问题