Сбой фрагмента с посылкой: невозможно выполнить маршалирование ошибки значения при вызове метода onPause

#android #android-fragments #serializable #jsonobject

#Android #android-фрагменты #сериализуемый #json

Вопрос:

Я уже некоторое время разрабатываю приложения для Android, но только недавно попал во фрагменты, и поэтому у меня возникает много проблем с обучением работе с ними. Одно из действий в моих приложениях содержит четыре разных фрагмента, каждый из которых отображает список элементов для пользователя. Каждый фрагмент создается сначала и отображается только после выбора и скрытия при выборе другой вкладки. После создания каждого из этих фрагментов в качестве аргумента фрагменту передается ArrayList JSONObjects следующим образом

             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, но было бы здорово, если бы кто-нибудь мог помочь мне работать с сериализуемыми или разделяемыми интерфейсами, чтобы исправить мою проблему, это было бы здорово. Также я реализовал сериализуемость как во фрагменте, так и в действии, как это было предложено другими.

Ответ №1:

Если вы уже получили нужные вам данные, просто удалите данные из пакета.

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

// remove it
getArguments().remove("myData");
  

Комментарии:

1. Это звучит как отличный способ сделать это

2. Теперь я уверен, что, удаляя каждое значение из моего пакета, я больше не получаю ошибок маршалирования, но не мог бы кто-нибудь объяснить, почему каждое значение должно быть удалено, даже если пакет больше не трогается после считывания? Очень любопытно!

3. я получал эту ошибку, когда запускал какое-либо действие, но это сработало. Спасибо

4. Отличный ответ, я не мог исправить эту ошибку до этого ответа. Почему необходимо удалять данные из пакета?

Ответ №2:

Что ж, мне удалось найти выход из этого, возможно, это не самый стандартный способ ведения дел, но на самом деле он решил мою проблему и может в какой-то степени помочь другим.

Вместо преобразования JSONArray, полученного из API, в массив JSON arraylist, а затем отправки его во фрагмент, я преобразовал массив 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();
  

Во фрагменте я получил пакет и преобразовал строку в JSONArray.

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

Затем я перебрал 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());
}
  

Теперь, когда состояние было сохранено, его можно легко восстановить в методе onCreateView следующим образом

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

Таким образом, мне не пришлось бы решать проблему с сериализуемостью или разделяемостью моих JSONObjects