关于this,this,this和this,我已经阅读过很多关于此问题的问题。
我的问题如下:我有一个驻留在服务器上的json数据。 Tha数据被缓存并作为gzip请求,因此整个大小约为110kb。如果您尝试使用firefox检索此数据(并使用firebug计算时间),则需要 3秒才能下载并显示。
同样的数据需要 10 - 15秒(有时甚至更多)才能下载并转换为我的Android应用上的字符串。 (请注意,我使用的是Nexus 10平板电脑,这是同类产品中处理速度最快的平板电脑之一。)
请参阅下面的代码:
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
// ... nameValuePairs omitted
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 3500);
HttpConnectionParams.setSoTimeout(params, 14000);
HttpConnectionParams.setTcpNoDelay(params, false);
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
params.setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
HttpClient httpclient = new DefaultHttpClient(params);
HttpPost httppost = new HttpPost(mContext.getResources().getString(R.string.newsUrl));
httppost.addHeader("Accept-Encoding", "gzip");
try {
// Add your data
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
Log.i(TAG, "NewsFetcher, Request started at: " + (int)(System.currentTimeMillis() / 1000));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
Log.i(TAG, "NewsFetcher, Request ended at: " + (int)(System.currentTimeMillis() / 1000));
if (response.getStatusLine().getStatusCode() == 200 || response.getStatusLine().getStatusCode() == 204 || response.getStatusLine().getStatusCode() == 304 ) {
Header contentEncoding = response.getFirstHeader("Content-Encoding");
String webAppResponse;
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
Log.i(TAG, "NewsFetcher, InputStream(gzip) received at : " + (int)(System.currentTimeMillis() / 1000));
webAppResponse = IOUtils.toString(new GZIPInputStream(response.getEntity().getContent()), "UTF-8");
} else {
Log.i(TAG, "NewsFetcher, InputStream(plain) received at : " + (int)(System.currentTimeMillis() / 1000));
webAppResponse = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
}
Log.i(TAG, "NewsFetcher, InputStream ended at : " + (int)(System.currentTimeMillis() / 1000));
// try to detect any error
try {
JSONArray webAppResultJSON = new JSONArray(webAppResponse);
ArrayList<NewsItem> parsedItems = parseJSON(webAppResultJSON);
return new FetchResult(UpdateStatus.FETCH_OK, parsedItems);
// ... exceptions omitted
} catch (Exception e) {
Log.e(TAG, "General Exception 1");
e.printStackTrace();
return new FetchResult(UpdateStatus.FETCH_GENERAL_ERROR, null);
}
} else {
return new FetchResult(UpdateStatus.FETCH_HTTP_ERROR, null);
}
// ... exceptions omitted
} catch (Exception e) {
Log.e(TAG, "General Exception 2");
e.printStackTrace();
return new FetchResult(UpdateStatus.FETCH_GENERAL_ERROR, null);
}
以下是logcat的结果
06-28 10:43:11.486: I/com.package.my.logic.NewsFetcher(3102): NewsFetcher, Request started at: 1372405391
06-28 10:43:17.986: I/com.package.my.logic.NewsFetcher(3102): NewsFetcher, Request ended at: 1372405397
06-28 10:43:17.986: I/com.package.my.logic.NewsFetcher(3102): NewsFetcher, InputStream(gzip) received at : 1372405397
06-28 10:43:30.266: I/com.package.my.logic.NewsFetcher(3102): NewsFetcher, InputStream ended at : 1372405410
如果从1372405410中减去1372405391,则 19秒!你能建议对上面的代码进行任何优化吗?
我还尝试使用HttpURLConnection
代替HttpPost
,但没有运气......
答案 0 :(得分:0)
似乎
webAppResponse = IOUtils.toString(new GZIPInputStream(response.getEntity().getContent()), "UTF-8");
占用大部分时间(13秒)。
我曾经写过这种方法,效果很好。也许它会比IOUtils更好:
public String inputStreamToString (InputStream inputStream) throws IOException {
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
}
只需将GZIPInputStream传递给它。
希望它会有所帮助