Cómo publicar el progreso para el análisis de archivos json de gran tamaño con GSON
Estimado Stackoverflowers,
Actualmente estoy analizando un archivo json grande de mis recursos sin procesar. Tuve que cambiar la lectura línea por línea con el uso de un objeto Reader en combinación con gson, para escapar de una excepción de memoria. Hasta aquí todo bien.
- Cómo enviar datos de formulario en retrofit2 android
- Cómo recuperar array multidimensional usando json en android
- ProgressDialog o ProgressBar ralentiza la aplicación que ejecuta Android 4.1
- Android studio no puede resolver import org.json.JSONObject
- ¿Cómo calcular el precio en la cantidad de datos JSON y Post datos?
Ahora todo esto sucede en una tarea asíncrona y quiero que el usuario sea notificado del progreso en algún tipo de pantalla de carga usando publishProgress()
.
InputStream raw = getResources().openRawResource(R.raw.json); Reader rd = new BufferedReader(new InputStreamReader(raw)); Gson gson = new Gson(); mReadObjects = gson.fromJson(rd, ReadObjectList.class);
Esta es la forma en que estoy leyendo el archivo por ahora, pero no tengo idea de si (y cómo) puedo obtener cualquier tipo de actualizaciones de progreso de GSON o el objeto Reader.
¡Cualquier ayuda es muy apreciada!
- Cómo obtener respuesta como String utilizando retrofit sin utilizar GSON o cualquier otra biblioteca en android
- Comparación de rendimiento y usabilidad de las bibliotecas Android JSON
- Ejemplo de inicio de sesión en Android mediante el método POST que utiliza la API REST
- Android gson streaming analizador o android.util.jsonreader?
- Cómo Caché los datos de Json para estar disponibles sin conexión?
- Envío de datos JSON de Android a PHP y escritura a archivo de texto
- ConstraintLayout forma de contenido cambiado si se desplaza
- Werid ClassCastException en TreeMap.containsKey ()
Tienes que escribir un Wrapper alrededor de un InputStream
(o un Reader
).
Algo como esto debería funcionar:
public class ProgressInputStream extends FilterInputStream { private final int size; private long bytesRead; private int percent; private List<Listener> listeners = new ArrayList<>(); public ProgressInputStream(InputStream in) { super(in); try { size = available(); if (size == 0) throw new IOException(); } catch (IOException e) { throw new RuntimeException("This reader can only be used on InputStreams with a known size", e); } bytesRead = 0; percent = 0; } public void addListener(Listener listener) { listeners.add(listener); } public void removeListener(Listener listener) { listeners.remove(listener); } @Override public int read() throws IOException { int b = super.read(); updateProgress(1); return b; } @Override public int read(@NonNull byte[] b) throws IOException { return updateProgress(super.read(b)); } @Override public int read(@NonNull byte[] b, int off, int len) throws IOException { return updateProgress(super.read(b, off, len)); } @Override public long skip(long n) throws IOException { return updateProgress(super.skip(n)); } @Override public void mark(int readLimit) { throw new UnsupportedOperationException(); } @Override public void reset() throws IOException { throw new UnsupportedOperationException(); } @Override public boolean markSupported() { return false; } private <T extends Number> T updateProgress(T numBytesRead) { if (numBytesRead.longValue() > 0) { bytesRead += numBytesRead.longValue(); if (bytesRead * 100 / size > percent) { percent = (int) (bytesRead * 100 / size); for (Listener listener : listeners) { listener.onProgressChanged(percent); } } } return numBytesRead; } public interface Listener { void onProgressChanged(int percentage); } }
Cómo utilizar:
ProgressInputStream raw = new ProgressInputStream(getResources().openRawResource(R.raw.json)); raw.addListener(new ProgressInputStream.Listener() { @Override public void onProgressChanged(int percentage) { publishProgress(percentage); } }); Reader rd = new BufferedReader(new InputStreamReader(raw));