簡體   English   中英

在具有3G連接的android上,檢索速度非常慢。 不適用於HSDPA或WiFi或仿真器

[英]Very slow retrieval on android with 3G connection. Not with HSDPA or WiFi or on emulator

這是一個復雜的問題,因為我不知道確切的問題。 主要問題是從Android應用程序中從REST服務器獲取非常小的數據包需要很長時間。 我將詳細介紹它,希望您能對我有所幫助。

問題

在以下情況下,數據檢索足夠快(+/- 100ms):

  • 已連接WiFi
  • 與HSDPA連接
  • 在將網絡設置(延遲和速度)設置為GPRS的Android Emulator上運行

但是,當我在連接不良的位置(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM