0

我有一个 android 应用程序,它以 JSON 格式下载其信息。

一个典型的 JSON 下载大约是 2,000-3,000 个字符。但我想强调一下,所以我创建了一个更大的文件(约 48,000 个字符)。随着文件的发展,这仍然很小,不到 50kb。

我遇到的问题是下载时我只得到 16144 个字符的数据。即只reader.readLine()返回一行包含 16144 个字符的行,client.execute(request, new BasicResponseHandler());. 显然,只有文件的一部分,我的 JSON 解析代码很快就会失败,因为它不是有效的 JSON 对象。

没有引发异常,因此它不是内存不足错误。而且这个问题在 HTC 渴望(2.2)和 Galaxy Nexus(4.1.1)上是可重复的,所以也不是特定于操作系统的。我已经在 Web 浏览器中测试了 URL,它工作正常,所有 JSON 都可用,因此它不是服务器错误。

问题

谁能指出为什么它只下载 16144 个字符,以及如何让它下载整个文件?

方法#1

HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(uri);
HttpResponse response = client.execute(request);

InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
    str.append(line);
}
in.close();
result.setJSONResult(str.toString());

方法#2

HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(uri);
HttpResponse response = client.execute(request);

String json = client.execute(request, new BasicResponseHandler());
result.setJSONResult(json);

注意 - 该 url 位于 LAN 网络上 (http://192.168.0.99:8080...),所以我没有包含它,因为它没有用处。

更新 - 已修复

修复了问题。最后我把它归结为文件传输问题,而不是手机的内存限制。虽然它可以在 PC (Chrome) 上运行,但我发现它在 android 以外的其他地方被破坏,例如在网站和其他浏览器 (Safari) 上无法使用原始 API 调用。根本问题是网络服务器的代理 ngix,想要缓冲更大的响应(超过 32kb),但是它从来没有对它用于缓冲的服务器文件夹具有写权限。这意味着它发送了部分文件,开始缓冲并由于无法写入而遇到严重错误。当它出错时,它停止发送文件的其余部分,因此它停止在异常数量的字节处。感谢你的帮助!

4

3 回答 3

1

这是因为这是字符串可以容纳的最大大小——Java 规范总是 2147483647 (2^31 - 1),数组的最大大小,String 类用于内部存储)或最大堆大小的一半(因为每个字符是两个字节),以较小者为准。

并且可能堆大小将小于 40kbs

您可以使用 json 阅读器而不是使用字符串来存储来自网络的数据,请参阅http://developer.android.com/reference/android/util/JsonReader.html

于 2012-09-03T10:45:40.227 回答
0

修复了问题。最后我把它归结为文件传输问题,而不是手机的内存限制。虽然它可以在 PC (Chrome) 上运行,但我发现它在 android 以外的其他地方出现故障,例如网站和其他浏览器 (Safari) 无法使用原始 API 调用。潜在的问题是网络服务器的代理 ngix,想要缓冲更大的响应(超过 32kb),但它从来没有对它用于缓冲的服务器文件夹具有写权限。这意味着它发送了部分文件,开始缓冲并由于无法写入而遇到严重错误。当它出错时,它停止发送文件的其余部分,因此它停止在异常数量的字节处。感谢你的帮助!

于 2012-09-07T16:07:35.830 回答
0

您正在使用基于行的阅读器来读取非基于行的数据。当您调用 时readLine,您要求它强制将读取的任何内容转换为一行文本。如果它实际上不是一行文本,这会破坏数据。

于 2012-09-03T10:41:12.643 回答