- 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/
我正在开发一个涉及位置的 Windows Phone 8.1 应用程序。我正在从我的 API 接收 Json 数据。我的 API 返回的数据如下所示: [{ "country": "India
我有一个 JSON 如下:- { "products": { "productsApp15": { "code": "productsApp16
我正在为生成 crate 编写一个 Spigot 插件。此 JsonReader 扫描宝藏池文件以查找我请求的特定设置。事情是,我不想一遍又一遍地复制相同的 while 循环,所以我决定做这个。 它成
我正在使用来自 gson 的 JsonReader 来解析 JSON,我的 JSON 解析适用于除此值之外的所有值: "tags": [ "String1", "S
我正在使用 JSON .NET 来解析我从网络服务收到的响应。问题是响应可能包含单个项目,或多个项目(数组),这将导致响应字符串略有不同。 单项响应: { "row": "1", "n
我试图从 JSON 对象输入流中读取第一个属性名称,然后根据它的值,可能“倒带”并读取整个对象。 我可以轻松读取第一个属性名称,例如 JsonReader reader = ...; while (r
我面临以下问题:我有这样的 json { "type": "objectType", "body": { //could be one of five differe
我的 Android 开发遇到错误。事实上,我尝试使用 stringtree 库解析 JSON Flux。因此,我在构建路径中导入库,但是当我启动应用程序时出现此错误:java.lang.NoClas
我正在使用以下类读取某个 URL 上的 JSON 文件并从中创建 JSONObject。当在屏幕上输出某些内容时,程序会终止,控制台中没有任何内容。这是代码: public class JsonRea
我必须重构应用程序的某些区域才能使用 Gson 中的流 API,但很快我就遇到了一个奇怪的问题,我不知道如何解决。我的类中的以下构造函数接收一个 JsonReader 并应该循环访问该对象的属性。 L
我正在学习 Java,并且正在尝试制作一个 Fortnite 统计跟踪应用程序。我正在使用 Fortnite 跟踪器 API 和 JsonReader 来读取返回的键和值。这工作正常,但问题是像“杀戮
我发现使用 http://ip-api.com/json 是获取必要的用户位置详细信息的简单方法。例如,来自网站的结果是: {"as":"AS37061 ONECOM","city":"Nairobi
我需要下载包含 20k 项的 Json 文件,同时我需要在 TextView 中显示百分比。现在我只测试代码的流程,所以我显示一个包含当前百分比的简单日志。所以我创建了一个 Observable 并且
我试图用 JsonReader 解析一个 JSON 文件。我使用 skipvalue() 函数转到下一个键,但解析器没有转到下一个键,而是跳转到文件末尾。 文件看起来像这样: { "data":
所以我一直在四处寻找,但不确定如何处理这个问题。我正在解析如下所示的 JSON { "foo1" : { /* data I want */ }, "foo2" : { /* data
首先我制作了一个应用程序,然后我开始对其进行测试(知道这不是好方法),解析等一切正常,但在我进行了几次测试后出现了错误: Newtonsoft.Json.JsonReaderException : E
我正在使用 JsonReader 从网站获取大量数据并保存到数据库。顺便说一句,每当读取器找不到对象项的值时,它就会失败并停止执行。 这是我的错误; System.err﹕ java.lang.Ill
我是 Xamarin Forms 的新手,我正在尝试创建一种从 API 请求项目列表的方法。但是,由于错误消息,我无法编译解决方案 "Cannot Convert From String to New
我是 jqgrid 的新手,最后我设置了一个网格。假设我需要设置 jsonReader 以便网格知道在 json 返回中从哪里获取我的网格数据。但是我尝试了几天后得到了空白单元格。 这是我的网格: j
阅读时here并使用 JsonWriter 和 JsonReader 创建一个大对象来发送和接收。我想跟踪发送的总字节数。 最佳答案 JsonWriter 或 JsonReader 中没有任何内容可以
我是一名优秀的程序员,十分优秀!