Good day!

There are a lot of topics about this error, but I haven’t found a clear solution After the user stops working with the application (5-10 hours), the program crashes when opening. If you immediately re-open the application, everything works without problems.

Here is the log:

Exception java.lang.RuntimeException: Unable to start activity ComponentInfo{com.vonegosh.creditcalc/com.vonegosh.creditcalc.ActivityInputParams}: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2484) android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2544) android.app.ActivityThread.access$900 (ActivityThread.java:150) android.app.ActivityThread$H.handleMessage (ActivityThread.java:1394) android.os.Handler.dispatchMessage (Handler.java:102) android.os.Looper.loop (Looper.java:168) android.app.ActivityThread.main (ActivityThread.java:5845) java.lang.reflect.Method.invoke (Method.java:) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:797) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:687) arrow_drop_down Caused by android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.os.Parcel.readParcelableCreator (Parcel.java:2420) android.os.Parcel.readParcelable (Parcel.java:2346) com.vonegosh.creditcalc.Calc.<init> (Calc.java:31) com.vonegosh.creditcalc.Calc$1.createFromParcel (Calc.java:39) com.vonegosh.creditcalc.Calc$1.createFromParcel (Calc.java:36) android.os.Parcel.readParcelable (Parcel.java:2355) android.os.Parcel.readValue (Parcel.java:2252) android.os.Parcel.readArrayMapInternal (Parcel.java:2601) android.os.BaseBundle.unparcel (BaseBundle.java:221) android.os.Bundle.getParcelable (Bundle.java:786) com.vonegosh.creditcalc.FragmentView2.onCreateView (FragmentView2.java:56) android.support.v4.app.Fragment.performCreateView (Fragment.java:1974) android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1067) android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1252) android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1234) android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated (FragmentManager.java:2046) android.support.v4.app.FragmentController.dispatchActivityCreated (FragmentController.java:174) android.support.v4.app.FragmentActivity.onStart (FragmentActivity.java:597) com.vonegosh.creditcalc.ActivityInputParams.onStart (ActivityInputParams.java:607) android.app.Instrumentation.callActivityOnStart (Instrumentation.java:1288) android.app.Activity.performStart (Activity.java:6264) android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2447) android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2544) android.app.ActivityThread.access$900 (ActivityThread.java:150) android.app.ActivityThread$H.handleMessage (ActivityThread.java:1394) android.os.Handler.dispatchMessage (Handler.java:102) android.os.Looper.loop (Looper.java:168) android.app.ActivityThread.main (ActivityThread.java:5845) java.lang.reflect.Method.invoke (Method.java:) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:797) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:687) 

Class

 public class Calc implements Parcelable { // Double global_platej = 0.0; ArrayList<Payment> payment_list; Context context; DB db; SharPref sharPref; LoanParametr lp_origin, lp; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yy"); private boolean isWithDopPayment = true; protected Calc(Parcel in) { payment_list = in.createTypedArrayList(Payment.CREATOR); lp_origin = in.readParcelable(LoanParametr.class.getClassLoader()); lp = in.readParcelable(LoanParametr.class.getClassLoader()); isWithDopPayment = in.readByte() != 0; } public static final Creator<Calc> CREATOR = new Creator<Calc>() { @Override public Calc createFromParcel(Parcel in) { return new Calc(in); } @Override public Calc[] newArray(int size) { return new Calc[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(lp, 0); dest.writeParcelable(lp_origin, 1); dest.writeArray(payment_list.toArray()); dest.writeBooleanArray(new boolean[]{isWithDopPayment}); } ////////////////////////много лишнего кода } 

As I understand it, the system cannot restore an instance of the Calc class in the protected Calc (Parcel in) method, but the reason is not clear to me.

UPD: In general, the error was repeated, but I was better prepared. I needed to find a way to repeat the error manually, because leaving the phone for a day in the hope that the system would kill the application was inappropriate. As a result, I went to the menu item "For Developers" - "Advanced" - "Limit of background processes" and set the value "Without background processes". Now we go into the main application, minimize it, go into another random application, the system kills the main application, we try to log in, the system tries to restore the objects, but it does not exit and the application crashes.

Now about the logic of the program. Placed instances of classes in the correct order, although the order generated by Android Studio.

  protected Calc(Parcel in) { lp = in.readParcelable(this.getClass().getClassLoader()); lp_origin = in.readParcelable(this.getClass().getClassLoader()); payment_list = in.createTypedArrayList(Payment.CREATOR); isWithDopPayment = in.readByte() != 0; } public static final Creator<Calc> CREATOR = new Creator<Calc>() { @Override public Calc createFromParcel(Parcel in) { return new Calc(in); } @Override public Calc[] newArray(int size) { return new Calc[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(lp, 0); dest.writeParcelable(lp_origin, 1); dest.writeList(payment_list); dest.writeBooleanArray(new boolean[]{isWithDopPayment}); } 

lp_origin is an instance of the class, which is filled in with the values ​​in advance and passed to the Calc constructor.

 public Calc(DB db, LoanParametr lp, Context context) { this.lp_origin = lp; this.db = db; this.context = context; sharPref = new SharPref(context); } 

lp is an instance of a class that is declared in the Calc class as a copy of lp_origin , after which operations are performed with it.

 public void FormDataArray() { //////много кода lp = new LoanParametr(lp_origin); //////много кода } 

This is the constructor for creating a copy.

 LoanParametr(LoanParametr lp) { this.NameTable = lp.getNameTable(); this.NameCredit = lp.getNameCredit(); this.summ = lp.getSumm(); this.DateOfIssue = lp.getDateOfIssue(); this.DateOfTheFirstPayment = lp.getDateOfTheFirstPayment(); this.term = lp.getTerm(); this.percent = lp.getPercent(); this.typeOfPayment = lp.getTypeOfPayment(); this.firstPayment = lp.firstPayment; this.firstInterestOnly = lp.getFirstInterestOnly(); this.weekend = lp.getWeekend(); this.lastDayMonth = lp.getLastDayMonth(); this.EDcom = lp.getEDcom(); this.Ezhcom = lp.getEzhcom(); this.simpleInterest = lp.getSimpleInterest(); this.raiffeisen = lp.getRaiffeisen(); } 

payment_list - ArrayList of the Payment class

 public class Payment implements Parcelable { private int number = 0; private long date_payment = 0L; private double platej = 0.0; private double dept = 0.0; private double percent = 0.0; private double remain_dept = 0.0; private double um_summ = 0.0; private double um_term = 0.0; private double izm_percent = 0.0; private double com = 0.0; private double insuranse = 0.0; private int type_plateja = 0; private int baks = 0; private int todebt = 0; private double izm_payment = 0; public double getIzm_payment() { return izm_payment; } public void setIzm_payment(int izm_payment) { this.izm_payment = izm_payment; } public Integer getNumber() { return number; } public Payment() { } public Integer getType_plateja() { return type_plateja; } public void setType_plateja(Integer type_plateja) { this.type_plateja = type_plateja; } public void setNumber(Integer number) { this.number = number; } public Long getDate_payment() { return date_payment; } public void setDate_payment(Long date_payment) { this.date_payment = date_payment; } public Double getPercent() { return percent; } public void setPercent(Double percent) { this.percent = percent; } public Double getDept() { return dept; } public void setDept(Double dept) { this.dept = dept; } public Double getPlatej() { return platej; } public void setPlatej(Double platej) { this.platej = platej; } public Double getRemain_dept() { return remain_dept; } public void setRemain_dept(Double remain_dept) { this.remain_dept = remain_dept; } public Double getUm_summ() { return um_summ; } public void setUm_summ(Double um_summ) { this.um_summ = um_summ; } public Double getUm_term() { return um_term; } public void setUm_term(Double um_term) { this.um_term = um_term; } public Double getIzm_percent() { return izm_percent; } public void setIzm_percent(Double izm_percent) { this.izm_percent = izm_percent; } public Double getCom() { return com; } public void setCom(Double com) { this.com = com; } public Double getInsuranse() { return insuranse; } public void setInsuranse(Double insuranse) { this.insuranse = insuranse; } public Integer getBaks() { return baks; } public void setBaks(Integer baks) { this.baks = baks; } public Integer getTodebt() { return todebt; } public void setTodebt(Integer todebt) { this.todebt = todebt; } public Payment(Integer number, Long date_payment, Double platej, Double dept, Double percent, Double remain_dept, Double um_summ, Double um_term, Double izm_percent, Double com, Double insuranse, Integer type_plateja, Integer baks, Integer todebt, Double izm_payment ) { this.number = number; this.date_payment = date_payment; this.platej = platej; this.dept = dept; this.percent = percent; this.remain_dept = remain_dept; this.um_summ = um_summ; this.um_term = um_term; this.izm_percent = izm_percent; this.com = com; this.insuranse = insuranse; this.type_plateja = type_plateja; this.baks = baks; this.todebt = todebt; this.izm_payment = izm_payment; } Payment(Parcel parcel) { this.number = parcel.readInt(); this.date_payment = parcel.readLong(); this.platej = parcel.readDouble(); this.dept = parcel.readDouble(); this.percent = parcel.readDouble(); this.remain_dept = parcel.readDouble(); this.um_summ = parcel.readDouble(); this.um_term = parcel.readDouble(); this.izm_percent = parcel.readDouble(); this.com = parcel.readDouble(); this.insuranse = parcel.readDouble(); this.type_plateja = parcel.readInt(); this.baks = parcel.readInt(); this.todebt = parcel.readInt(); this.izm_payment = parcel.readDouble(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(number); parcel.writeLong(date_payment); parcel.writeDouble(platej); parcel.writeDouble(dept); parcel.writeDouble(percent); parcel.writeDouble(remain_dept); parcel.writeDouble(um_summ); parcel.writeDouble(um_term); parcel.writeDouble(izm_percent); parcel.writeDouble(com); parcel.writeDouble(insuranse); parcel.writeInt(type_plateja); parcel.writeInt(baks); parcel.writeInt(todebt); parcel.writeDouble(izm_payment); } public static final Parcelable.Creator<Payment> CREATOR = new Parcelable.Creator<Payment>() { @Override public Payment createFromParcel(Parcel source) { return new Payment(source); } @Override public Payment[] newArray(int size) { return new Payment[size]; } }; } 

In the end, what happens (the "==" sign means - returned when the system tries to recover data)

lp == origin

lp_origin == ClassNotFoundException when unmarshalling

payment_list == empty Arraylist

Someone please explain how the data recovery procedure? How does it use ClassLoader and, if possible, how to fix the problem?

 public void writeToParcel(Parcel dest, int flags) { 

What is the flags variable?

  • 2
    Record and read the values ​​must be in the same order. You have a different order - YuriySPb
  • Thank you, the error does not repeat! - Arsen Shogenov
  • Wrote in reply) - Juriy Spb
  • Try passing the flags to not write the entries 0 and 1, but those that came in the argument. When reading, use the class loader class that you write - i.e. not this , but as it used to be - LoanParametr.class.getClassLoader() - Yuriy SPb
  • one
    Hmm ... Well ... And what if they are not recorded in a row, but between them write / read what is the thread of another ?? - Yuriy SPb

1 answer 1

Record and read the values ​​must be in the same order. Your order is different.

So just change the write / read order to the same.