使用3G连接在Android上检索非常慢。不使用HSDPA或WiFi或模拟器

时间:2013-08-13 11:41:36

标签: android rest tomcat7 3g

这是一个复杂的问题,因为我不知道确切的问题。主要问题是从我们的Android应用程序中获取REST服务器中的一小部分数据需要很长时间。我将详细描述它,希望你能帮助我。

问题

在以下情况下,数据检索足够快(+/- 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的工作速度足够快,但我不确定。 代理后面的tomcat7上的Restlet服务。我们使用ChallengeAuthenticator进行身份验证。

1 个答案:

答案 0 :(得分:0)

我已经通过切换到Apache的HttpClient解决了这个问题。 我不确定为什么这是一个解决方案,因为谷歌建议使用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;
}