wake-up-neo.com

TransactionTooLargeException nur für Nougat

Ich habe eine App, die auf Geräten mit Android-Versionen niedriger als Nougat funktioniert.

Wenn ich die App auf einem Gerät mit Nougat starte und die Starttaste drücke, stürzt die App ab und in logcat habe ich:

!!! FAILED BINDER TRANSACTION !!!  (parcel size = 1819712)
Unhandled exception
Java.lang.RuntimeException: Android.os.TransactionTooLargeException: data parcel size 1819712 bytes
    at Android.app.ActivityThread$StopInfo.run(ActivityThread.Java:3781)
    at Android.os.Handler.handleCallback(Handler.Java:751)
    at Android.os.Handler.dispatchMessage(Handler.Java:95)
    at Android.os.Looper.loop(Looper.Java:154)
    at Android.app.ActivityThread.main(ActivityThread.Java:6119)
    at Java.lang.reflect.Method.invoke(Native Method)
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:886)
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:776)
 Caused by: Android.os.TransactionTooLargeException: data parcel size 1819712 bytes
    at Android.os.BinderProxy.transactNative(Native Method)
    at Android.os.BinderProxy.transact(Binder.Java:615)
    at Android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.Java:3636)
    at Android.app.ActivityThread$StopInfo.run(ActivityThread.Java:3773)
    at Android.os.Handler.handleCallback(Handler.Java:751) 
    at Android.os.Handler.dispatchMessage(Handler.Java:95) 
    at Android.os.Looper.loop(Looper.Java:154) 
    at Android.app.ActivityThread.main(ActivityThread.Java:6119) 
    at Java.lang.reflect.Method.invoke(Native Method) 
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:886) 
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:776) 

Gibt es eine einfache Lösung? Dieses Problem tritt nur bei Nougat auf.

5
nuka_cola

Ich habe das gleiche Problem. Dies wurde von vielen Entwicklern im Google-Forum beanstandet. Ihre Antwort ist WAI (Arbeit wie beabsichtigt), weil sie nicht empfehlen, zu viele Daten im Status zu speichern. Der Rat ist also, einem Intent nur sehr grundlegende Argumente hinzuzufügen. Wenn Sie Daten zwischen Aktivitäten oder Fragmenten senden möchten, 

  • Speichern Sie die Daten in einer (temporären) Datei und übergeben Sie den Datei-URI. Diese Option ist wahrscheinlich die einzige Option, wenn Sie Große Datenmengen in eine völlig andere App übertragen möchten. Speichern Sie die Daten In der Anwendungsinstanz. 
  • Erstellen Sie einen Singleton-Container mit den Daten, die Sie weitergeben.
  • Wenn Sie FragmentStatePageAdapter verwenden, fügen Sie den folgenden Code hinzu, um das Speichern von Statusdaten zu vermeiden.

    @Override    
    public Parcelable saveState() {
            Bundle bundle = (Bundle) super.saveState();
            bundle.putParcelableArray("states", null); // Never maintain any states from the base class to avoid TransactionTooLargeException
            return bundle;
    }
    

Referenz:

https://issuetracker.google.com/issues/37103380

https://www.neotechsoftware.com/blog/Android-intent-size-limit

5
flame3

Aus der Dokumentation der TransactionTooLargeException-Klasse

Der Binder-Transaktionspuffer hat eine begrenzte feste Größe, derzeit 1Mb , die von allen für den Prozess laufenden Transaktionen gemeinsam genutzt wird. Daher kann diese Ausnahme ausgelöst werden, wenn viele Transaktionen ausgeführt werden, selbst wenn die meisten einzelnen Transaktionen eine moderate Größe aufweisen.

Haben Sie die Größe der Daten überprüft, die Sie über eine niedrigere Android-API weiterleiten? 

Ich empfehle Ihnen, diese Größe zu protokollieren, bevor Sie Daten auf Android 7.0/7.1 und andere übertragen. Bei verschiedenen Android-Versionen benötigen Ihre Daten möglicherweise einen unterschiedlichen Speicherplatz.

es passiert mehr, wenn die Aktivität einige Fragmente enthält und jeder die onSaveInstance ausführt. Wenn das Fragment onCreateView die Ansicht immer neu starten soll (kein Ansichtsstatus muss os wiederhergestellt werden), dann rootview.setSaveFromParentEnabled (false); um onSaveInstanceState () der Ansicht zu verhindern. Das kann helfen.

0
lannyf

Hier gilt das gleiche. Keine schnelle Lösung für dieses Problem.

Meine Lösung bestand darin, die Daten temporär in der Datenbank oder in der Datei zu speichern. Es werden auch nur Daten zwischen Aktivitäten und Fragmenten übertragen.

Ich denke, das ist auch ein besseres Entwurfsmuster für die meisten Anwendungsfälle mit großen Daten.

0

Ich habe dieses Problem durch Speichern der Daten in einer Datei behoben. Vielen Dank für alle Antworten.

0
nuka_cola