Это немного сложный вопрос, поскольку я не знаю точной проблемы. Основная проблема заключается в том, что для получения очень маленького пакета данных с нашего сервера REST из нашего приложения для Android требуется очень много времени. Я опишу его подробно и надеюсь, что вы можете мне помочь.Очень медленный поиск на Android с 3G-соединением. Не с HSDPA или WiFi или на эмуляторе
Проблема
извлечения данных достаточно быстро (+/- 100 мс), когда:
- связи с WiFi
- связи с HSDPA
- Запуск на эмуляторе Android с сетевыми настройками (задержки и скорости), установленной на GPRS
Однако, когда я использую телефон в месте с плохим соединением (3G вместо HSDPA), вызов служб может занять до 4 секунд (текущий тайм-аут в AsyncTask).
Android
Это код, используемый для взаимодействия с сервисами:
/**
* 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, но я не уверен. Службы Restlet на tomcat7 за прокси. Для аутентификации мы используем ChallengeAuthenticator.