亲爱的Stackoverflowers,
我目前正在从我的原始资源中解析一个大的json文件.我不得不逐行更改读取使用Reader对象和gson,以逃避内存不足异常.到现在为止还挺好.
现在这一切都发生在异步任务中,我希望通过使用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);
这是我现在正在阅读文件的方式,但我不知道是否(以及如何)我可以从GSON或Reader对象获得任何类型的进度更新.
任何帮助是极大的赞赏!
解决方法
您必须围绕InputStream(或Reader)编写包装器.
像这样的东西应该工作:
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); } }
如何使用:
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));