Límite de tamaño de datos de intención y excepción TransactionTooLargeException
Registro de fallos:
Aunque es obvio a primera vista que el fallo fue causado por la comunicación del Binder, al igual que el problema de OOM, es fácil caracterizar el problema, pero es No es fácil localizar el problema.
Descripción oficial:
1. TransactionTooLargeException
En pocas palabras: todas las llamadas AIDL de un proceso de aplicación utilizan un búfer de transacciones de Binder, y el tamaño de este El búfer es de solo 1 Mb. Cuando el tamaño total de todos los parámetros de llamadas remotas o los valores de retorno de estas llamadas excede 1 Mb, se generará una excepción TransactionTooLargeException.
2. Parcelables y paquetes
El búfer de transmisión de Binder es un área de tamaño limitado, con un tamaño de 1 MB. Este búfer se utiliza para la comunicación entre todos los procesos, es decir, la comunicación de Binder. . Estas transferencias incluyen onSaveInstanceState, startActivity y otras interacciones con el sistema. Cuando los datos transferidos exceden este tamaño, se generará una excepción.
Especialmente el método onSaveInstanceState, debido a que necesita proporcionar datos cuando regresa la Actividad, el sitio web oficial recomienda que el tamaño de los datos no supere los 50 K.
Nota:
1. ¿Tendremos problemas de serialización mientras pasemos datos a través de Bundle?
No, al transferir datos entre actividades, primero debemos considerar el problema de la comunicación entre procesos, y Android utiliza el mecanismo Binder para resolver el problema de la comunicación entre procesos. Cuando se trata de procesos cruzados, los datos complejos implicarán el proceso de serialización y deserialización, que está destinado a ser un proceso de transferencia de valor (copia profunda).
El fragmento en sí no implica procesos cruzados. Aunque Bundle se utiliza para transmitir datos, no pasa por Binder, es decir, no hay serialización ni deserialización. El paquete relacionado con la transferencia de datos de fragmentos en realidad transfiere una referencia al objeto original.
Conclusión: pasar un paquete a través de setArguments (Bundle) de Fragment. Aunque Bundle se usa para transmitir datos, no pasa a través de Binder, es decir, no hay serialización ni deserialización. El paquete relacionado con la transferencia de datos de fragmentos en realidad transfiere una referencia al objeto original. (Como experimento, pase un objeto cuando aparezca DialogFragment. Después de modificar los datos en el Diálogo, el objeto se modifica en la Actividad)
2. La información del paquete guardada en la Actividad onSaveInstanceState se almacena en la memoria, y debido a que implica la preservación del estado de la Actividad, debe ser administrado por el proceso ActivityManager, por lo que se requiere la transmisión de Binder para realizar una comunicación entre procesos para pasar los datos del paquete al ActivityManager.
Por lo tanto, onSaveInstanceState también implica la transmisión de Binder, que naturalmente está limitada por el tamaño del búfer de Binder.
3. La implementación de FragmentStatePagerAdapter es defectuosa, porque su implementación predeterminada continuará guardando el historial de datos de estado de las instancias históricas de Fragment. , y gradualmente Después de acumular y guardar datos, el tamaño del paquete de datos enviado finalmente superó el límite de 50 KB
/mmbiz_jpg/liaczD18OicSz3ctQsLW8lGAAMWev0a16PZoqAev5CViaTTBuUZrWNG1m27sIicfKrYZicMmjdP4WwFO53vicWToC3Ag/640?wx_fmt= jpeg amp;wxfrom=5amp;wx_lazy=1amp;wx_co =1
Utilice el método postSticky() de EventBus para enviar el evento, que almacenará en caché el evento en el objeto stickyEvents Map para que el evento pueda extraerse y enviarse al componente registrado la próxima vez. registrado.
Recibir:
Enlace de referencia:
Entrevistador frecuente: ¿Cuánto tamaño de datos puede transmitir Intent? | ¡Paga las sugerencias de Ali!
¿Dónde existen los datos de Android----onSaveInstanceState? ¿Por qué el tamaño es limitado?
Análisis de causa de TransactionTooLargeException