- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要下载包含 20k 项的 Json 文件,同时我需要在 TextView 中显示百分比。现在我只测试代码的流程,所以我显示一个包含当前百分比的简单日志。所以我创建了一个 Observable 并且我这样做了:
private void downloadAirports()
{
final OkHttpClient mOkHttpClient = new OkHttpClient();
final Request mRequest = new Request.Builder().url(SERVICE_ENDPOINT).build();
Observable.create(new Observable.OnSubscribe<String>()
{
@Override
public void call(Subscriber<? super String> subscriber)
{
try {
InputStream inputStream;
okhttp3.Response response = mOkHttpClient.newCall(mRequest).execute();
if (response.isSuccessful())
{
inputStream = response.body().byteStream();
long len = response.body().contentLength();
Log.d("str",String.valueOf(len));
String progress = "0";
subscriber.onNext(progress);
final int bufferSize = 1024;
boolean flag = false;
final char[] buffer = new char[bufferSize];
final StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(inputStream, "UTF-8");
long total = 0;
airp = new ArrayList<AirportObject>();
int count =0;
Gson gson = new Gson();
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
airp = new ArrayList<>();
long i = 0;
reader.beginArray();
while (reader.hasNext())
{
AirportObject message = gson.fromJson(reader, AirportObject.class);
airp.add(message);
i++;
byte [] arr = message.toString().getBytes();
total = total + arr.length;
Log.d("%",String.valueOf(total));
double p = total/len * 100;
subscriber.onNext(String.valueOf(p));
}
reader.endArray();
reader.close();
//airp = Arrays.asList(airportArray);
subscriber.onCompleted();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).subscribeOn(Schedulers.newThread())
.subscribe(new Subscriber<String>() {
long size, perc;
public void onCompleted()
{
Log.wtf("on complete","On complete");
}
@Override
public void onError(Throwable e)
{
e.printStackTrace();
}
@Override
public void onNext(final String progress) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run()
{
// Log.d("%",progress);
// textView.setText("Download aeroporti in corso:"+progress+"%");
}
});
}
});
}
但是我给了变量len(有效字节数)和变量total两个不同的值。那么while循环中如何获取JsonReader下载的有效字节值呢?
谢谢
最佳答案
您可以重新考虑您的进度模型,以使其更加简单和分离。如果将进度状态封装到 InputStream
中会怎样 decorator并在阅读时暴露它?
它是如何工作的?首先,您必须封装要装饰的真实输入流。还需要一些中间状态来计算读取的字节数并将该值与预期长度值进行比较。一旦某个事件在某种情况下发生,只需通过已经封装的订阅者触发比率值。下面的输入流装饰器使用 Float
比率,其中值始终在 [0;1]
范围内。为什么?让您的 View 决定如何呈现标准化比率: TextView 中的百分比、进度条或其他任何内容。百分比基本上只是一个人性化的未规范化值,而在给出比率时,您要确保始终传递0..1
值并且不传递关心生成器站点的“用户友好性”(想象一下,如果有一天您将公开 promille,hm-m-m —— 这会在其他地方破坏您的代码,这些代码会期望百分比而不是 promilles)。
public final class ProgressInputStream
extends InputStream {
private final Subscriber<? super Float> subscriber;
private final InputStream inputStream;
private final long expectedLength;
private final long lengthPerPercent;
private long actualLength;
private long currentChunkLength;
private ProgressInputStream(final Subscriber<? super Float> subscriber, final InputStream inputStream, final long expectedLength) {
this.subscriber = subscriber;
this.inputStream = inputStream;
this.expectedLength = expectedLength;
lengthPerPercent = (long) ceil((double) expectedLength / 100);
}
public static InputStream progressInputStream(final Subscriber<? super Float> subscriber, final InputStream inputStream, final long expectedLength) {
return new ProgressInputStream(subscriber, inputStream, expectedLength);
}
@Override
public int read()
throws IOException {
return (int) count(inputStream.read());
}
@Override
public int read(final byte[] bytes)
throws IOException {
return (int) count(inputStream.read(bytes));
}
@Override
public int read(final byte[] bytes, final int offset, final int length)
throws IOException {
return (int) count(inputStream.read(bytes, offset, length));
}
@Override
public long skip(final long n)
throws IOException {
return count(inputStream.skip(n));
}
@Override
public void close()
throws IOException {
inputStream.close();
}
private long count(final long read) {
if ( read != -1 ) {
if ( actualLength == 0 ) {
subscriber.onNext(0F);
}
currentChunkLength += read;
actualLength += read;
if ( currentChunkLength >= lengthPerPercent ) {
currentChunkLength = 0;
if ( actualLength < expectedLength ) {
subscriber.onNext((float) actualLength / expectedLength);
} else if ( actualLength == expectedLength ) {
subscriber.onNext(1F);
subscriber.onCompleted();
} else {
throw new AssertionError("Must never happen. A bug in the code around?");
}
} else if ( actualLength == expectedLength ) {
subscriber.onNext(1F);
subscriber.onCompleted();
}
}
return read;
}
}
现在,将进度计算器封装在装饰器中,典型的用法可能如下所示:
Observable
.<Float>create(subscriber -> {
final File file = new File("/tmp/some.json");
try ( final InputStream inputStream = progressInputStream(subscriber, new BufferedInputStream(new FileInputStream(file)), file.length());
final JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8")) ) {
reader.beginArray();
while ( reader.hasNext() ) {
gson.<AirportObject>fromJson(reader, AirportObject.class);
}
reader.endArray();
} catch ( final IOException ex ) {
throw new RuntimeException(ex);
}
})
.subscribe(new Subscriber<Float>() {
@Override
public void onNext(final Float ratio) {
out.printf("Read: %s%%\n", (long) (ratio * 100));
}
@Override
public void onCompleted() {
out.println("Downloaded");
}
@Override
public void onError(final Throwable ex) {
throw new RuntimeException(ex);
}
});
检查一下,现在您不必在解析 JSON 时计算进度,从而使您的代码更清晰。此外,您可以在其他地方重复使用这样的流,而不仅仅是 Gson 等。
我只在桌面系统上测试过它,而不是在真实设备上(没有 Activity 、UI 线程或 HTTP 网络,只有一个 JSON 文件和标准输出输出),但这个概念可以很容易地迁移到 Android 系统,只需最少的努力.这是长度为 84047 的文件的输出:
Read: 0%
Read: 9%
Read: 19%
Read: 29%
Read: 38%
Read: 48%
Read: 58%
Read: 68%
Read: 77%
Read: 87%
Read: 97%
Read: 100%
Downloaded
关于android - 如何获取 JsonReader 字节来计算百分比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41587185/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!