2014-01-24 3 views
29

Ich bekomme diese Ausnahme, wenn ich meine App verlasse und sie nach einiger Zeit öffne. Meine Hauptaktivität besteht aus einem ViewPager mit drei verschiedenen Fragmenten. Ich mache auch einige Sachen in der Anwendungsklasse, von denen ich denke, dass sie sich nicht auf das Problem beziehen.Proguard verursacht RuntimeException (Unmarshalling unbekannter Typcode) in Parcelable Klasse

Dies ist die Ausnahme:

RuntimeException (@Parcel:readValue:2065) {Unable to start activity ComponentInfo{com.emu/com.emu.ActivityMain}: java.lang.RuntimeException: Parcel [email protected]: Unmarshalling unknown type code 2131361816 at offset 332}

ich viele dieser Ausnahme auf den Handys in Google Analytics geschieht zu sehen. Alle von ihnen sind die gleichen außer Nummer nach readValue und Hex-Nummer nach @, die in der obigen Ausnahme 2065 und 419526d0 sind.

Die Ausnahme zeigt keine Codezeile an. Ich habe danach gesucht und es scheint, dass es sich um falsches Schreiben auf Paket handelt. Obwohl ich kein Paket in meiner MainActivity habe. Ich weiß nicht, was das verursachen könnte.

--- BEARBEITEN ------------------------------------------ ------------------------------

Ich reproduzierte die Ausnahme. Dies passiert, wenn die App mit der Home-Taste verlassen wird und nach dem Öffnen einer anderen speicherintensiven App aus dem Speicher gelöscht wird. Beim erneuten Start passiert Ausnahme. Bis jetzt dachte ich, dass das Schließen der App von der letzten Aufgabe oder von DDMS die gleiche Wirkung hat, aber anscheinend nicht.

@EricWoodruf hat mir geholfen, dieses Paket irgendwo in der importierten Bibliothek zu finden. Ich finde das Paket in PagerSlidingTabStrip, das ich aus dem Internet heruntergeladen hatte. Dies ist das Paket bezogenen Code, aber ich weiß wirklich nicht, was falsch ist, hier:

public class PagerSlidingTabStrip extends HorizontalScrollView 
{ 
    @Override 
    public void onRestoreInstanceState(Parcelable state) 
    { 
     SavedState savedState = (SavedState) state; 
     super.onRestoreInstanceState(savedState.getSuperState()); 
     currentPosition = savedState.currentPosition; 
     requestLayout(); 
    } 

    @Override 
    public Parcelable onSaveInstanceState() 
    { 
     Parcelable superState = super.onSaveInstanceState(); 
     SavedState savedState = new SavedState(superState); 
     savedState.currentPosition = currentPosition; 
     return savedState; 
    } 

    static class SavedState extends BaseSavedState 
    { 
     int currentPosition; 

     public SavedState(Parcelable superState) 
     { 
      super(superState); 
     } 

     private SavedState(Parcel in) 
     { 
      super(in); 
      currentPosition = in.readInt(); 
     } 

     @Override 
     public void writeToParcel(Parcel parcel, int flags) 
     { 
      super.writeToParcel(parcel, flags); 
      parcel.writeInt(currentPosition); 
     } 

     public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() 
     { 
      @Override 
      public SavedState createFromParcel(Parcel in) 
      { 
       return new SavedState(in); 
      } 

      @Override 
      public SavedState[] newArray(int size) 
      { 
       return new SavedState[size]; 
      } 
     }; 
    } 
} 

---- EDIT 2 ------------------ -----------------------------------------------

Nachdem ich das Problem reproduzieren konnte, fand ich heraus, dass dies nur in Artifact passiert, das von meinem Schlüssel signiert und programmiert wurde! Das Debug hat das Problem nicht!

Ich deaktiviert Proguard auf Artefakt und es funktioniert wie ein Charme ohne Ausnahme. Aber, was Proguard führt zu diesem Problem?

Ich habe versucht, diese Zugabe ProGuard aber hat nicht funktioniert:

-keep class toolfa.android.base.ui.PagerSlidingTabStrip { *; } 
-dontwarn toolfa.android.base.ui.PagerSlidingTabStrip 

diese Config meiner aktuellen proguard ist:

-keep class com.nineoldandroids.** { *; } 
-dontwarn com.nineoldandroids.** 

-keep class ir.adad.** { *; } 
-dontwarn ir.adad.** 

-keep class android.support.v4.** { *; } 
-dontwarn android.support.v4.** 

-keep class toolfa.android.base.ui.PagerSlidingTabStrip { *; } 
-dontwarn toolfa.android.base.ui.PagerSlidingTabStrip 

-keep class toolfa.android.sega.ActivityEmulator { *; } 
-keep class toolfa.android.sega.Zip { *; } 
+0

Es ist ein wenig schwierig, Ihnen mit solchen allgemeinen Fehler zu helfen, ohne irgendeinen Code zu sehen ...:/ –

+0

Haben Sie irgendwelche kundenspezifischen Klassen, die parcelable implementieren? –

+0

Übrigens würden Sie erwarten, dass die Zahl nach @ anders ist, da dies einer Objekt-ID entspricht und eine Speicheradresse sein kann. –

Antwort

41

Wie wir in den Kommentaren fand heraus, war die Ausnahme der Ergebnis von ProGuard verschleiern Parcelable Klassen. Das Update ist dieser Schnipsel in der ProGuard Konfigurationsdatei enthalten:

-keepclassmembers class * implements android.os.Parcelable { 
    static ** CREATOR; 
} 

Ich denke, das spezifische Problem war hier, dass ProGuard das CREATOR Mitglied PagerSlidingTabStrip verschleierte, aber da SavedState ist eine Unterklasse von View.BaseSavedState, war die Super Mitglied immer noch verfügbar (deshalb hat es keine BadParcelableException geworfen), aber das verwendet eine andere Datenstruktur und schrieb die benutzerdefinierten Attribute nicht in die Parcel Ausgabe.

Es gibt eine empfohlene Konfiguration für Android-Anwendungen in der ProGuard Manual, mit detaillierten Erklärungen zu Einträgen.Beispielsweise müssen Sie alle Klassennamen beibehalten, die im Manifest oder in anderen XML-Dateien verwendet werden.

+0

Ich habe das gleiche Problem, aber proguared verursacht andere Probleme, gibt es eine andere Möglichkeit, dieses Problem zu beheben? – Nininea

-3

Ich denke ich weiß, warum das passiert. Ich bin mir nicht sicher, also könnte ich mich irren.

In meinem Fall verwende ich also einen Viewpager in meiner App, um einige Datenbankdaten anzuzeigen (mit dem Cursor). Wenn ich die App im Hintergrund belasse und nach einer langen Zeit (ein paar Stunden) wieder aktiviere, entscheidet sich Android, meine App zu beenden. Nach dem Fortsetzen der App wird meine Aktivität wiederhergestellt. Der zugrunde liegende Datensatz in meinem Adapter wird jedoch nicht wiederhergestellt.

über dieses Problem zu gehen, ich bin für Daten in onResume() IF getCount() 0 zurück

An Ihrer Seite Neuabfragen, ich glaube, das gleiche zu Ihrer App geschieht. Versuchen Sie, ein Log in Ihre onResume zu platzieren und sehen Sie, ob dies der Fall ist?

Verwandte Themen