2013-08-13 4 views
0

Это немного сложный вопрос, поскольку я не знаю точной проблемы. Основная проблема заключается в том, что для получения очень маленького пакета данных с нашего сервера 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.

ответ

0

Я решил эту проблему, переключившись на HttpClient Apache. Я не уверен, почему это решение, поскольку 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; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^