我遇到了这个" bug" (引用,因为我不确定它是否只是我错过了一些非常简单明了的东西)帮助我的GF代码一些简单的Android GUI。
此应用程序通过互联网获取一些数据,并显示可视化数据的图表。
我有一些像这样的代码:
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class DownloadTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
private String downloadUrl(String urlString) throws IOException {
InputStream stream = null;
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
stream = conn.getInputStream();
return readStream(stream, conn.getContentLength());
} finally {
if (stream != null) {
stream.close();
}
}
}
public String readStream(InputStream stream, int bufferLength) throws IOException {
char[] buffer = new char[bufferLength];
Reader reader = new BufferedReader(new InputStreamReader(stream, "ascii"));
reader.read(buffer, 0, bufferLength);
return new String(buffer);
}
}
我使用上面的代码作为基类,并在其他类中的私有类中实现onPostExecute
。
问题是,当我在onPostExecute
得到结果时,字符串不完整。注意:我写了服务器,所以我可以保证内容长度是正确的。
前几百个字符是正确的,但在某些时候,我开始看到未知的字符。我尝试使用字节数组来读取原始流,并看到未知字符只是0。所以流看起来像:[... 54 52 53 ... 0 0 0 0 0 0 0 ...]。基本上,正确的字节后跟全零。
我想知道为什么要切断流,以及如何让它正确读取整个响应。注意:这个&#34; bug&#34;在一些手机上非常一致地发生,而在其他手机上却不那么一致。
关于数据的更多细节,它是纯文本,逗号或空格分隔的行,由\ n分隔的行(如上所述,我写了服务器。我以前使用逗号,将其更改为空格只是测试它是否是问题所在。数据大小约为2000字节,我认为并不大。
谢谢你看看这个!
答案 0 :(得分:2)
我想知道为什么要切断流,以及如何让它读取 整体反应正确。
当您从来自网络的InputStream
读取时,并非所有字节都可以同时全部可用。
public String readStream(InputStream stream, int bufferLength) throws IOException {
StringBuilder builder = new StringBuilder();
int read = 0;
byte[] buffer = new byte[8 * 1024];
while ((read = stream.read(buffer)) > 0) {
builder.append(new String(buffer, 0, read));
}
return builder.toString();
}