【问题标题】:Android low connectivity cancel async http taskAndroid低连接取消异步http任务
【发布时间】:2014-12-09 04:35:35
【问题描述】:

我有一个前台服务,可以从服务器运行我所有的上传/下载媒体文件(音频、视频、图片)。对于纯文本消息,我使用 AsyncTask 将消息发送到服务器。 在上传或下载消息时,我会在消息旁边显示一个进度条。

有人告诉我,在使用该应用程序时,有时短信很长时间没有通过,并且进度条一直在旋转。 这就是我为所有 http 请求获取默认 httpclient 的方式。

private static DefaultHttpClient httpclient;  // my static httpclient

 public synchronized static DefaultHttpClient getNewHttpClient() {
    if(httpclient!=null){
        Log.d(TAG, "returning existing httpclient");
        return httpclient;      
    }

    try {
        Log.d(TAG, "creating new httpclient");

        KeyStore trustStore = KeyStore.getInstance(KeyStore
                .getDefaultType());
        trustStore.load(null, null);

        SSLSocketFactory sf = new SixDegreeSSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);


        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        HttpConnectionParams.setConnectionTimeout(params, 6 * 1000);
        ClientConnectionManager ccm = new ThreadSafeClientConnManager(
                params, registry);
        ConnManagerParams.setTimeout(params, 6000);
        httpclient=new DefaultHttpClient(ccm,params);
        return httpclient;
    } catch (Exception e) {
        Log.d(TAG, "Exception creating defaultClient");
        e.printStackTrace();
        return new DefaultHttpClient();
    } 
}

我已经使用了连接超时。我在 AsyncTask 的 doInBackground 方法中执行 http post

@Override      
protected Boolean doInBackground(Object... argList) {       
try {           
HttpResponse response;   

if (this.requestMethod.equals(GET)) {

            HttpGet httpGet = new HttpGet(url);

            response = client.execute(httpGet);

        } else {

            HttpPost httpPost = new HttpPost(url);
            Log.d(TAG, "http post ");
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

            if (values != null) {
                for (Map.Entry<String, String> entry : values.entrySet()) {
                    nameValuePairs.add(new BasicNameValuePair(entry
                            .getKey(), entry.getValue()));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
            }

            response = client.execute(httpPost);
            Log.d(TAG, "client execute");
        }

        /* setting a response code. */
        this.responseCode = response.getStatusLine().getStatusCode();

        returnflag = (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK);

        // Get the response
        StringBuilder str = new StringBuilder();
        try{
            if (returnflag) {
                BufferedReader rd = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));
                String line = "";               
                while ((line = rd.readLine()) != null) {
                str.append(line);
                }
                rd.close();
            }
        } finally{
            try{
                if(response.getEntity()!=null)
                    response.getEntity().consumeContent();  // consume the entity content
            } catch(IOException e){
                e.printStackTrace();
            }

        }

        this.responseString = str.toString();

    } catch (UnknownHostException ex) {
        System.out.println(TAG + " UnknownHostException ");
        ex.printStackTrace();
    } catch (IOException e) {
        System.out.println(TAG + " responseCode " + responseCode);
        e.printStackTrace();
        returnflag = false;
    }
    catch (NullPointerException ex){
        ex.printStackTrace();
        returnflag = false;
    }
    catch (IndexOutOfBoundsException ex)
    {   ex.printStackTrace();
        returnflag = false;
    } catch(Exception e){
        e.printStackTrace();
    }
    finally {

    }

    return returnflag;
    }

基于布尔返回标志,我在 postExecute 中处理结果,其中 extendedHandler 是我在活动中实现的接口的一个实例

protected void onPostExecute(Boolean result) {
if(result) {
        iRequester.onRequestSuccess(responseString, requestCode);
        if(extendedHandler != null) extendedHandler.onRequestSuccessExtended(responseString,    requestCode, this.tagData);
    }
    else {
        iRequester.onRequestFailure(responseCode, requestCode);
        if(extendedHandler != null) extendedHandler.onRequestFailureExtended(responseCode, requestCode, this.tagData);
    }

}

在这个实现下,如果连接不好,我应该如何处理或者在一定时间后取消tast。我不确定仅使用 HttpConnectionParams.setSoTimeout 是否可行。在取消任务之前,有什么方法可以知道消息是否已传递到服务器并且它只是在等待响应。 如果需要进一步澄清,请告诉我。

谢谢

【问题讨论】:

  • setConnectionTimeout 为我工作。

标签: android networking android-asynctask


【解决方案1】:

为什么不从服务器发回 ACK 以确认文本已成功接收?

JSON格式的确认结果:

{status: "ok")

【讨论】:

  • 如果成功,我会收到来自服务器的 JSON 响应。基于此,我删除了消息的进度条。
  • final int TIMEOUT=5000; 并在HttpConnectionParams.setSoTimeout 和计时器中使用它,计时器将停止任务并显示连接不稳定/慢...等消息
  • 如果成功,我会收到来自服务器的 JSON 响应。基于此,我删除了消息的进度条。问题是在低连接期间,进度条旋转了很长时间,我认为这是因为它从未收到服务器的响应。我试图找到在连接性较差的特定情况下如何处理请求。假设他们发送了一条短信,显示进度条并花费时间,然后他们关闭了应用程序,然后异步任务消失了,它永远无法处理来自服务器的响应。
  • 或者您甚至可以为互联网连接定义一个广播接收器,并设置一个连接标志,并在连接超时且该标志设置为 false 时停止任务。
  • 我绝对可以实现,但我担心如果在消息插入我们的服务器数据库但尚未发回 JSON 响应之后发生超时,那么它将在设备上显示消息失败并且在重新发送消息时可能会导致重复。我不确定这是否有意义
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多