![](/img/trans.png)
[英]How to send email(Gmailsend,JSSEProvider) using wifi and 3g(HSDPA,GPRS) connection on android
[英]Very slow retrieval on android with 3G connection. Not with HSDPA or WiFi or on emulator
這是一個復雜的問題,因為我不知道確切的問題。 主要問題是從Android應用程序中從REST服務器獲取非常小的數據包需要很長時間。 我將詳細介紹它,希望您能對我有所幫助。
問題
在以下情況下,數據檢索足夠快(+/- 100ms):
但是,當我在連接不良的位置(3G而不是HSDPA)上使用電話時,呼叫服務最多可能需要4s(AsyncTask上的當前超時)。
安卓系統
這是用於與服務進行通信的代碼:
/**
* Get json string from service
*
* @param urlString url of service
* @return json result from service
*/
private String callService(String urlString) {
InputStream in = null;
HttpURLConnection c = null;
Scanner s = null;
String json = null;
try {
URL url = new URL(urlString);
Log.i(getClass().getName() + ".callService()", "start calling service: " + url);
long start = java.lang.System.currentTimeMillis();
try {
setAuthentication();
c = (HttpURLConnection) url.openConnection();
c.connect();
in = new BufferedInputStream(c.getInputStream());
s = new Scanner(in);
s.useDelimiter("\\A");
json = s.next();
} catch (IOException e) {
Log.e(getClass().getName() + ".callService()", "error: " + e.getMessage(), e);
}
Log.i(getClass().getName() + ".callService()", "complete calling service: (" + (System.currentTimeMillis() - start) + " ms) " + url);
return json;
} catch (Exception e) {
Log.e(getClass().getName() + ".callService()", "error: " + e.getMessage(), e);
} finally {
if (s != null) {
s.close();
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e(getClass().getName() + ".callService()", "error: " + e.getMessage(), e);
}
}
if (c != null) {
c.disconnect();
}
}
return json;
}
我嘗試了幾種方法來調用此方法,但是當前使用AsyncTask完成:
/**
* Retrieve json from service
*
* @param url url of service
* @return json
*/
public String getJsonFromServiceBasic(String url) {
ServiceTask task = new ServiceTask();
try {
return task.execute(url).get(4000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Log.e(getClass().toString() + " getJsonFromServiceBasic(" + url + ")", " interrupt exception: " + e.getMessage(), e);
} catch (ExecutionException e) {
Log.e(getClass().toString() + " getJsonFromServiceBasic(" + url + ")", " execution exception: " + e.getMessage(), e);
} catch (TimeoutException e) {
task.cancel(true);
Log.e(getClass().toString() + " getJsonFromServiceBasic(" + url + ")", " timeout exception: " + e.getMessage(), e);
} catch (Exception e) {
Log.e(getClass().toString() + " getJsonFromServiceBasic(" + url + ")", " timeout exception: " + e.getMessage(), e);
}
return null;
}
/**
* AsyncTask way of calling service
*/
class ServiceTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
String json = callService(urls[0]);
return json;
}
}
AndroidManifest.xml:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
服務
我不認為這是問題所在,因為它可以與HSDPA一起快速運行,但是我不確定。 代理后面的tomcat7上的Restlet服務。 我們正在使用ChallengeAuthenticator進行身份驗證。
我已經通過切換到Apache的HttpClient解決了這個問題。 我不確定為什么這是Google建議使用HttpURLConnection的解決方案,但對我來說這可行。
使用此方法代替callService方法將解決我的互聯網訪問速度較慢的問題。
private String callServiceClient(String urlString) {
String json = null;
HttpParams httpParams = new BasicHttpParams();
int connection_Timeout = 5000;
HttpConnectionParams.setConnectionTimeout(httpParams, connection_Timeout);
HttpConnectionParams.setSoTimeout(httpParams, connection_Timeout);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
httpClient.getCredentialsProvider().setCredentials(new AuthScope(null, -1),
new UsernamePasswordCredentials(user, password));
HttpGet httpget = new HttpGet(urlString);
// Execute the request
HttpResponse response;
try {
response = httpClient.execute(httpget);
// Examine the response status
StatusLine responseCode = response.getStatusLine();
Log.i(getClass() + ".callServiceClient()", "responsecode: " + responseCode);
if (responseCode.getStatusCode() != HttpStatus.SC_OK) {
return json;
}
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to worry about connection release
if (entity != null) {
// A Simple JSON Response Read
InputStream instream = entity.getContent();
json = convertStreamToString(instream);
// now you have the string representation of the HTML request
instream.close();
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.