Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Muy grande respuesta SOAP – Android- fuera de error de memoria

Tengo una aplicación donde necesito descargar una gran cantidad de datos vía una llamada de SOAP a un webservice en la aplicación cuando está funcionada por primera vez. La respuesta se envía a una función que convierte el XML y almacena los datos en un archivo db.

Los datos son más de 16 MB de tamaño y tengo un java.lang.OutOfMemoryError cada vez.

Modificar el webservice para dar cantidades más pequeñas de datos no es una opción.

¿Hay una manera de poder descargar los datos grandes? Algo como un InputStream tal vez?

Este es mi codigo

public Protocol[] getProtocols() { String METHOD_NAME = "GetProtocols"; String SOAP_ACTION = "urn:protocolpedia#GetProtocols"; Log.d("service", "getProtocols"); SoapObject response = invokeMethod(METHOD_NAME, SOAP_ACTION); return retrieveProtocolsFromSoap(response); } private SoapObject invokeMethod(String methodName, String soapAction) { Log.d(TAG, "invokeMethod"); SoapObject request = GetSoapObject(methodName); SoapSerializationEnvelope envelope = getEnvelope(request); return makeCall(envelope, methodName, soapAction); } 

¿Alguien puede sugerir qué se debe hacer en este caso?

Gracias y saludos Mukul

  • ¿Cómo puedo llamar correctamente a mi PHP webservice usando ksoap2-android?
  • Cuándo usar Soapobject y SoapPrimitive
  • REST y SOAP webservice en android
  • Android, envío de XML a través de HTTP POST (SOAP)
  • Cómo configurar jabón Header usando ksoap2 - android
  • Recibir y procesar un Dictionary <string, List <string >> desde Soap usando KSoap2
  • ¿Cual es mejor? Alto número de llamadas de servicio web (mensajes SOAP) o alta cantidad de datos en un único mensaje de jabón?
  • Generar Java desde WSDL para usarlo en Android con el cliente SOAP ksoap2-android?
  • 3 Solutions collect form web for “Muy grande respuesta SOAP – Android- fuera de error de memoria”

    Dos estrategias para ayudarle a resolver este problema:

    1. Guarde su flujo XML de SOAP directamente en el disco mientras lo descarga. No lo guarde en la memoria.
    2. Analizarlo utilizando un analizador de estilo SAX, donde no carga todo el DOM en memoria, sino que lo analiza en trozos.

    Dependiendo del tipo de XML que esté manejando, el uso de los analizadores SAX suele ser más difícil en el código; Usted tendrá que hacer un seguimiento de muchas cosas usted mismo, y no será capaz de "saltar" de sección a sección de su árbol DOM. Pero el consumo de memoria será mucho menor.

    Sin embargo, tenga en cuenta que muchas bibliotecas de comunicación de red de "alto nivel" normalmente cargan todo el XML DOM en la memoria, lo cual podría ser el caso aquí. Es probable que tenga que crear y administrar la conexión HTTP usted mismo y, a continuación, analizar manualmente el resultado.

    Sólo una actualización, encontré que el método de "llamada" en AndroidHttpTransport se estaba quedando sin memoria en esta línea –

      if (debug) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[256]; while (true) { int rd = is.read(buf, 0, 256); if (rd == -1) break; bos.write(buf, 0, rd); } bos.flush(); buf = bos.toByteArray(); //Goes out of memory here responseDump = new String(buf); is.close(); is = new ByteArrayInputStream(buf); 

    La llamada a toByteArray tiene una gran cantidad de memoria, por lo que para superar esto, en lugar de convertir la respuesta a una matriz de bytes, ahora directamente escribirlo en un archivo XML, y esto se guarda en una ubicación de mi elección. Aquí –

     if (debug) { FileOutputStream bos = new FileOutputStream("/data/data/com.mypackage.myapp/response.xml"); byte[] buf = new byte[1048576]; int current = 0; int i=0; int newCurrent = 0; while ((current = inputStream.read(buf)) != -1) { newCurrent = newCurrent + current; Log.d("current", "Current = " + current + " total = "+newCurrent+" i = "+i++); bos.write(buf, 0, current); } bos.flush(); } 

    El dispositivo ya no se queda sin memoria, y tengo un método de análisis personalizado que toma este XML y lo escribe en el DB.

    ¡Fijo!

    He descargado / copiado HttpTransportSE java clase de aquí (después de copiado, algunos errores de código pueden ocurrir, pero son todos rápido fijable) y agregó a mi paquete:

     https://github.com/mosabua/ksoap2-android/blob/master/ksoap2-j2se/src/main/java/org/ksoap2/transport/HttpTransportSE.java 

    Eliminado de mi clase de conexión esta fila:

     import org.ksoap2.transport.HttpsTransportSE; 

    Y sustituí este código en mi nuevo archivo HttpTransportSE.java:

     if (debug) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[256]; while (true) { int rd = is.read(buf, 0, 256); if (rd == -1) break; bos.write(buf, 0, rd); } bos.flush(); buf = bos.toByteArray(); //Goes out of memory here responseDump = new String(buf); is.close(); is = new ByteArrayInputStream(buf); } 

    con este

     if (debug) { FileOutputStream bos = new FileOutputStream(file); byte[] buf = new byte[256]; while (true) { int rd = is.read(buf, 0, 256); if (rd == -1) { break; } bos.write(buf, 0, rd); } bos.flush(); } 

    Donde "file" es un objeto de archivo simple como new File ("/ sdcard /", "myFile.xml") por ejemplo

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.