亲爱的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));

android – 如何使用GSON发布大型json文件解析的进度的更多相关文章

  1. android – 如何使用GSON发布大型json文件解析的进度

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

  2. android – IncompatibleClassChangeError com.google.gson.annotations.SerializedName.value

    当用户从Play商店更新应用程序时,我们在Samsung设备中收到IncompatibleClassChangeError.请检查下面的日志.代码如下:LoginResponse是我的POJO课程.将返回JSON字符串,这是服务器响应.解决方法看起来像三星问题..很多人不仅与gsonlib有同样的问题,而且还有其他库.我认为你不能做太多,只等三星开发人员解决这个问题.已经这个问题是在三星开发者论坛

  3. android – Gson中的RuntimeException解析JSON:无法调用受保护的java.lang.ClassLoader()而没有args

    我假设我可以通过单独保存位置对象中的关键字段来解决这个问题,但如果可能的话,保存位置对象会很好.我看到有一个ExclusionStrategy对象可用于排除字段,但我不确定是否可以/应该使用它来排除我位置内的额外内容…

  4. Android Twitter Fabric SDK与Google GSON发生冲突

    我在将TwitterFabricSDK集成到我的应用程序时遇到了困难.我按照Twittertutorial的步骤进行操作,但是当我尝试用gradle构建我的项目时,我得到了这个错误:我尝试从我的app模块lib文件夹中删除我的静态Gson库,之后一切都很顺利.删除从gradle模块依赖项添加twittersdk的行时也一样,所以我很确定这两者之间存在某种冲突,我正在寻求解决它.任何帮助将不胜感激!

  5. android – 用gson解析JSON对象

    我正在尝试解析JSON,如:有了GSON,制作但是获得错误预期BEGIN_ARRAY但在第1行第2列是BEGIN_OBJECT如何在数组中解析这些数字?解决方法您将首先想要创建一个模型类,GSON可以将您的json绑定到:然后你可以打电话

  6. android – 如何通过Retrofit在@Query中传递自定义枚举?

    我将toString()用于其他目的.解决方法正如@DawidSzydo所提到的,我在Retrofit中误解了Gson的用法.它仅用于响应/请求解码/编码,但不用于@Query/@Url/@Pathe.t.c.对于他们来说,Retrofit使用Converter.Factory将任何类型转换为String.以下是将@Serializedname作为任何Enum的值传递给Retrofit服务时自动使用的代码.转换器:EnumUtils:改造创造:08.18更新添加kotlin类似物:在日志中,您将看到:使用

  7. android – GSON反序列化自定义对象数组

    我正在尝试使用GSON在Android中序列化/反序列化JSON.我有两个类看起来像这样:和:我正在使用GSON来序列化/反序列化数据.我像这样序列化:这将生成如下所示的JSON:我这样反序列化:我打电话的时候收到错误.我不知道这个错误意味着什么.我不认为自己做了任何严重的错误.有帮助吗?解决方法将您的代码更改为:使用Interfaces是一个很好的做法,GSON要求.Gson将javascript中的数组“[]”转换为LinkedList对象.在您的代码中,GSON尝试在_users字段中注入一个Lin

  8. android – 使用GSON解析并放入对象列表

    我发现这篇文章:http://www.dev-articles.com/article/Google-gson-and-list-of-objects-386003看起来它正在尝试做我想要的,它解析我的json并将它们放入对象列表中.我没有得到的,或者文章遗漏的东西,是“Project”类如何被使用.它似乎无处不在.编辑:感谢yorkw,我现在有:但是我在Type上获得了红色标记.“类型无法解析为

  9. android – Retrofit:如何在请求中指定逗号分隔的参数?

    我正在尝试重构我的代码以使用Retrofit进行一些FoursquareAPI调用,但是没有找到一个正确的示例来说明如何指定一个查询参数,该参数有两个用逗号分隔的值.我的基本网址如下:我的其余网址是这样的:我的界面的第一个实现:然后提出这样的请求:但是,上面给了我以下错误:第二个实现(在查看一些使用Query参数的SO响应之后.注意:一旦我找到了ll?对于基本相同的问题,它们是不同的工具.>利用Retrofit的内置转换器机制;)从单词到代码:共:

  10. Android studio Gradle无法找到方法compile()

    过去两天我试图找到解决这个问题的方法,但没有运气.我想尝试包含GSONlib.进入我的android项目.这是我的文件夹结构的图片:现在在我的build.gradle中,我有以下内容:我也右键单击了gson-2.2.4.jar并将其添加为lib.当我编译时,我得到以下错误:谁能帮我这个?如果您需要更多信息,请告诉我!和接受的答案.两个答案都说同样的话.添加/导入jar文件并编辑build.gradle文件后,gradlew清理.HTH.编辑:有两个build.gradle文件.您应该编辑项目文件夹下的bu

随机推荐

  1. bluetooth-lowenergy – Altbeacon库无法在Android 5.0上运行

    昨天我在Nexus4上获得了Android5.0的更新,并且altbeacon库停止了检测信标.似乎在监视和测距时,didEnterRegion和didRangeBeaconsInRegion都没有被调用.即使RadiusNetworks的Locate应用程序现在表现不同,一旦检测到信标的值,它们就不再得到更新,并且通常看起来好像信标超出了范围.我注意到的一点是,现在在logcat中出现以下行“B

  2. android – react-native动态更改响应者

    我正在使用react-native进行Android开发.我有一个视图,如果用户长按,我想显示一个可以拖动的动画视图.我可以使用PanResponder实现这一点,它工作正常.但我想要做的是当用户长按时,用户应该能够继续相同的触摸/按下并拖动新显示的Animated.View.如果您熟悉Google云端硬盘应用,则它具有类似的功能.当用户长按列表中的任何项目时,它会显示可拖动的项目.用户可以直接拖

  3. android – 是否有可能通过使用与最初使用的证书不同的证书对其进行签名来发布更新的应用程序

    是否可以通过使用与最初使用的证书不同的证书进行签名来发布Android应用程序的更新?我知道当我们尝试将这样的构建上传到市场时,它通常会给出错误消息.但有没有任何出路,比如将其标记为主要版本,指定市场中的某个地方?解决方法不,你不能这样做.证书是一种工具,可确保您是首次上传应用程序的人.所以总是备份密钥库!

  4. 如何检测Android中是否存在麦克风?

    ..所以我想在让用户访问语音输入功能之前检测麦克风是否存在.如何检测设备上是否有麦克风.谢谢.解决方法AndroidAPI参考:hasSystemFeature

  5. Android – 调用GONE然后VISIBLE使视图显示在错误的位置

    我有两个视图,A和B,视图A在视图B上方.当我以编程方式将视图A设置为GONE时,它将消失,并且它正下方的视图将转到视图A的位置.但是,当我再次将相同的视图设置为VISIBLE时,它会在视图B上显示.我不希望这样.我希望视图B回到原来的位置,这是我认为会发生的事情.我怎样才能做到这一点?编辑–代码}这里是XML:解决方法您可以尝试将两个视图放在RelativeLayout中并相对于彼此设置它们的位置.

  6. android – 获得一首歌的流派

    我如何阅读与歌曲相关的流派?我可以读这首歌,但是如何抓住这首歌的流派,它存放在哪里?解决方法检查此代码:

  7. android – 使用textShadow折叠工具栏

    我有一个折叠工具栏的问题,在展开状态我想在文本下面有一个模糊的阴影,我使用这段代码:用:我可以更改textColor,它可以工作,但阴影不起作用.我为阴影尝试了很多不同的值.是否可以为折叠文本投射阴影?

  8. android – 重用arm共享库

    我已经建立了armarm共享库.我有兴趣重用一个函数.我想调用该函数并获得返回值.有可能做这样的事吗?我没有任何头文件.我试过这个Android.mk,我把libtest.so放在/jni和/libs/armeabi,/lib/armeabi中.此时我的cpp文件编译,但现在是什么?我从objdump知道它的名字编辑:我试图用这个android.mk从hello-jni示例中添加prebuild库:它工作,但libtest.so相同的代码显示以下错误(启动时)libtest.so存在于libhello-j

  9. android – 为NumberPicker捕获键盘’Done’

    我有一个AlertDialog只有一些文本,一个NumberPicker,一个OK和一个取消.(我知道,这个对话框还没有做它应该保留暂停和恢复状态的事情.)我想在软键盘或其他IME上执行“完成”操作来关闭对话框,就像按下了“OK”一样,因为只有一个小部件可以编辑.看起来处理IME“Done”的最佳方法通常是在TextView上使用setonEditorActionListener.但我没有任何Te

  10. android – 想要在调用WebChromeClient#onCreateWindow时知道目标URL

    当我点击一个带有target=“_blank”属性的超链接时,会调用WebChromeClient#onCreateWindow,但我找不到新的窗口将打开的新方法?主页url是我唯一能知道的东西?我想根据目标网址更改应用行为.任何帮助表示赞赏,谢谢!

返回
顶部