如何获取块中的 JSON 数据以报告进度? [复制]
Posted
技术标签:
【中文标题】如何获取块中的 JSON 数据以报告进度? [复制]【英文标题】:How to get JSON data in chunks to report on progress? [duplicate] 【发布时间】:2011-10-05 18:44:12 【问题描述】:我需要通过 REST API 下载联系人数据,我得到的是 JSON 格式。问题是,可能有很多联系人,所以我想观察进度(已经下载了多少联系人)并向用户报告(带有进度条,下面的代码在线程中运行)。
但是,似乎行 client.execute(getRequest);建立连接并一次性下载整个内容,即我的 InputStream 阅读器(以块的形式获取内容)似乎没用。现在我想知道如何让它分块工作,以便我可以报告进度?
/** prepare html get request */
HttpGet getRequest = new HttpGet(url[0]);
getRequest.addHeader("Authorization", "OAuth " + myTokens.get_access_token());
/** execute HTML request */
DefaultHttpClient client = new DefaultHttpClient();
JSONArray records = null;
HttpResponse response = client.execute(getRequest);
/** init response handlers for input stream */
InputStream input = new BufferedInputStream(response.getEntity().getContent());
byte data[] = new byte[MAX_BUFFER_SIZE];
long totalContactsCount = -1;
int readContactsCount = 0;
int currentByteReadCount = 0;
/** read response from inpus stream */
while ((currentByteReadCount = input.read(data)) != -1)
String readData = new String(data, 0, currentByteReadCount);
dataString.append(readData);
// then +1 progress on every ...,... (JSON object separator)
if (readData.indexOf(",") >= 0)
readContactsCount++;
// publishing the progress....
if (totalContactsCount > 0)
publishProgress((int)(readContactsCount * 100 / totalContactsCount));
input.close();
/** transform response into JSONArray */
String result = dataString.toString();
//... convert into JSONArray
【问题讨论】:
如果你读取的缓冲区中有多个 ',' 怎么办? 你说得对——我这里简化了代码,但是会发生的情况是如果最新读取包含多个联系人,UI中的进度条不会达到100%(代码会继续读取输入流)。但是,问题仍然是下载似乎在我打开 InputStream 之前发生。 【参考方案1】:您可以先向 Web 服务询问其拥有的联系人总数(例如 100,000),然后向其询问联系人的各个“页面”(例如 100 个联系人/页)。随着每一页的到达,您更新进度条。如果页面请求失败,只需重试该请求并继续处理。这应该是一种比尝试在一个大规模请求中获得所有 10 万联系人更可靠和有效的方法。
【讨论】:
好主意!我能够以另一种方式解决它,但这绝对是我可以在另一个应用程序中使用的概念 - 谢谢!【参考方案2】:不幸的是,从DefaultHttpClient
的文档中可以看出,execute
方法返回的 HTTP 响应已经解析,因此已经从网络读取,因此您无法插入输入流。该流已准备好供您阅读,但正如您所注意到的,一旦它被检索到。你必须使用另一种策略。例如,尝试使用套接字 API 进行连接。
【讨论】:
谢谢。我尝试了套接字方法,但它也适用于 HttpUrlConnections(稍微简单一点)。URL urlObject = new URL(url[0]);
HttpURLConnection conn = (HttpURLConnection) urlObject.openConnection();
conn.addRequestProperty("Authorization", "OAuth " + myTokens.get_access_token());
InputStream input = conn.getInputStream();
啊,完美。 HttpURLConnection
万岁! :)以上是关于如何获取块中的 JSON 数据以报告进度? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用从 Swift 3 中的滑块中选择的 JSON 数据更新 tableviewcell?
AFHttpclient 在块中获取 json 主体但外部函数返回 null
如何以编程方式获取 FCM 发送、打开和转换的报告? [复制]