Good afternoon, ladies and gentlemen. I am writing an application for android, and I encountered the following problem ... After my application is open, I open other demanding applications: games, browser, etc., then android destroys the active fragment / activity in my application, freeing up so . resources for the system. Then I try to open the application again, but it is overloaded and painted. Error description:

java.lang.RuntimeException: Unable to start activity ComponentInfo {my_app / md530ee4884bf1bb4f3619af03b33af6888.MainActivity}: java.lang.RuntimeException: Parcel android.os.Parcel@7b3d21a: unmarshalling type 21 2140.a. (ActivityThread.java:2426) at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2490) at android.app.ActivityThread.-wrap11 (ActivityThread.java) at android.app.ActivityThread $ H.handleMessage (ActivityThread.java : 1354) at android.os.Handler.dispatchMessage (Handler.java:102) at android.os.Looper.loop (Looper.java:148) at android.app.ActivityThread.main (ActivityThread.java Zin443) at java .lang.reflect.Method.invoke (Native Method) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:728) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java: 618) Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@7b3d21a: Unmarshalling unknown type code 21310998 24 at offset 460 at android.os.Parcel.readValue (Parcel.java:2340) at android.os.Parcel.readSparseArrayInternal (Parcel.java:2675) at android.os.Parcel.readSparseArray (Parcel.java:1967) at android.os.Parcel.readValue (Parcel.java:2321) at android.os.Parcel.readArrayMapInternal (Parcel.java:2614) at android.os.BaseBundle.unparcel (BaseBundle.java:221) at android.os.Bundle .getSparseParcelableArray (Bundle.java:856) at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:997) at android.support.v4.app.FragmentManagerImpl.moveToSerate in an account of it, in the form of a file in support of the file in an account of this, in the form of a file. support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1234) at android.support.v4.app.FragmentManagerImpl.dispatchCreate (FragmentManager.java:2041) at android.support.v4.app.FragmentContraphraphr.appraptane.java:2041) at android.support.v4.app.FragmentContraphraph.apprapt.phrathrapt.vr.apprach.phragonMap.raft.crypt.phragonMmp. java: 163) at android.support.v4.app.FragmentActivity.onCreate (FragmentActivity.java.7331) at android.support.v7.app.AppCompatActivity.onCreate (AppCompatActivity.java:85) at md530ee4884bf1bb4f3619af03b33af6888.MainActivity. : 1130) at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2379) ... 9 more

How to make android not destroy fragment / activity? Or maybe some other solution? I am writing in C # Xamarin , but in Java the code is almost identical.

Calling a fragment from the MainActivity :

SupportFragment fragment = new ItemCharacteristicsFragment(); var fragmentManager = SupportFragmentManager.BeginTransaction(); fragmentManager.Replace(Resource.Id.flContent, fragment); fragmentManager.AddToBackStack(null); fragmentManager.CommitAllowingStateLoss(); 

The fragment itself:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using SupportFragment = Android.Support.V4.App.Fragment; using ShopMobile; using Android.Text; namespace StozharyApp.Classes { class ItemCharacteristicsFragment : SupportFragment { public ItemElement Item { get; set; } public override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Create your fragment here } public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.Inflate(Resource.Layout.ItemCharacteristics, container, false); TextView txtCharacteristics = view.FindViewById<TextView>(Resource.Id.txtCharacteristics); txtCharacteristics.TextFormatted = Html.FromHtml(Item.Desc); return view; } } } 
  • Why do you use the CommitAllowingStateLoss method instead of Commit to complete a transaction? It’s a bad idea to allow loss of state, if your application starts crashing with the Commit method and offers to use CommitAllowingStateLoss, then with a probability of 99.9% you are not performing this transaction somewhere there. - xkor
  • Maybe I'm doing something wrong, because the experience of programming under the android is still not enough. While I found the only solution, so that the application does not crash when using recovery, use CommitAllowingStateLoss, this does not save when the fragment is destroyed by the system, and then not restored. - Igor
  • Well, show me how you create a fragment in the activit, otherwise you only have a piece of creating a transaction directly, and where and how you use it is not clear, but much depends on it. - xkor
  • one
    Doom, but in vain did not specify, remember that if you do not want problems with restoring states, never pass anything into the fragment directly through the constructor or assignment of values ​​directly to the field. Any parameters must be passed to the fragment ONLY via the Bundle in the setArguments method and, accordingly, all these parameters must be primitives, strings, arrays, lists, Parcelable or Serializable. Yes, it is not convenient, but such is the android. - xkor
  • one
    but the point is that when restoring a state, the fragment will be recreated not by your code but by the fragment manager and it will do it through the default constructor (which is without parameters), and accordingly nothing that you passed through the constructor with parameters or directly initializing the fields will not be restored, saved Only the content received via getArguments (for xamarin, this method will probably be seen as a property of Arguments) - xkor

3 answers 3

Judging by the stack of traces, when you restore the state of an activation or a fragment, it is not possible to restore some Parcelable object, most likely you used some poorly implemented Parcelable inheritor when transferring parameters / arguments to the activation / fragment or saving its state. Check what you transfer and save.

  • I do not save the fragment state at all, in the Android SDK it is said that this is done automatically when adding a fragment to Back Stack. How can a program implement a fragment preservation mechanism? - Igor
  • only the internal state is automatically saved, as well as some parameters for the views that are specified in the id markup, if you need to save the contents of the class fields or something else, then you need to do it yourself, save in the onSaveInstanceState method, and restore, for example, onCreate from parameter savedInstanceState. - xkor 2:41 pm

The only option to restore the fragment in onSaveInstanceState

Save to Activity

 protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); ... } 

Pull in the Activity itself in the onCreate method, check the Bundle savedInstanceState variable for null , if empty, load new data, if not, restore it from the Bundle . The same code for fragment recovery only in the onActivityCreated method

    I don’t know for sure if it will help you or not, but the fragment has the setRetainInstance (boolean) method, and if you call it with the argument true, then the fragment will not be called onCreate and onDestroy, i.e. the fragment will be recreated and not recreated.

    Call it in the onCreate fragment method.

    • Already tried to do so does not help! In the Andoid SDK I found that setRetainInstance does not work if addToBackStack () is used. - Igor