2015-01-11 9 views
8

Değerli Stackoverflowers ile ayrıştırma büyük json dosyası için ilerleme nasıl yayımlanır. Hafıza dışı bir durumdan kurtulmak için okuma çizgisini gson ile birlikte bir Reader nesnesini kullanarak değiştirmek zorunda kaldım. Çok uzak çok iyi.Şu anda benim çiğ kaynaklarından büyük json dosyası ayrıştırma am</p> <p>, GSON

Artık tüm bunlar bir zaman uyumsuz görevde oluyor ve kullanıcıya bir yükleme ekranındaki ilerlemeyi publishProgress() kullanarak bildirmesini istiyorum.

InputStream raw = getResources().openRawResource(R.raw.json); 
Reader rd = new BufferedReader(new InputStreamReader(raw)); 
Gson gson = new Gson(); 
mReadObjects = gson.fromJson(rd, ReadObjectList.class); 

Bu

şimdilik dosyayı okuyorum yoldur, ama ben hiçbir ipucu eğer (ve nasıl) GSON veya Okuyucu nesneden ilerleme güncellemeleri her türlü alabilirsiniz var.

Herhangi bir yardım büyük beğeni topluyor!

cevap

2

InputStream (veya Reader) ürününün etrafında bir Wrapper yazmanız gerekir. Böyle

şey çalışmalıdır:

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); 
    } 
} 

nasıl kullanılır: Bu sadece bir oy vardı ve doğru olarak işaretlenmemiş neden bilmiyorum

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)); 
+0

. Bu bana çok yardımcı oldu, bunun için teşekkürler. –