2

最近、Android アプリのネットワーク コードの一部をリファクタリングして、Google が推奨するHTTPUrlConnectionを使用しました。以前は、Apache の HTTPClient を使用していました。それらのいずれかが関連しているかどうかはわかりません。

最近ネットワーク コードに加えたもう 1 つのことは、呼び出しに AsyncTask を使用することです。以前は、メイン スレッドで作業を行っていたため (明らかに悪いことでした)、データを取得するときにアプリケーションがハングしたように見えました。問題は、AsyncTask に切り替えてから、かなり頻繁にタイムアウト エラーが発生することです。

このタイムアウト エラーが発生するのはなぜですか?

 java.net.ConnectException: failed to connect to <url> (port 80): connect failed: ETIMEDOUT (connection timed out)

これがネットワーク呼び出しを行う AsyncTask です。

private class PostToPHP extends AsyncTask<PostToPHP, Void, String>
{
    private String functionName;
    private ArrayList<NameValuePair> postKeyValuePairs;

    public PostToPHP(String function, ArrayList<NameValuePair> keyValuePairs)
    {
        functionName= function;
        postKeyValuePairs = keyValuePairs;
    }

    @Override
    protected void onPreExecute()
    {
        progressDialog = ProgressDialog.show(BaseActivity.getInstance(), "Loading", "Please wait...", true, false);
    }

    @Override
    protected String doInBackground(PostToPHP... params)
    {
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair(FUNCTION_NAME, functionName));
        for (int i = 0; i < postKeyValuePairs.size(); i++) {
            nameValuePairs.add(postKeyValuePairs.get(i));
        }

        try {
            URL url = new URL("www.myurl");
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Accept-Charset", iso-8859-1);
            OutputStream os = urlConnection.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, iso-8859-1));
            writer.write(getEncodedPostParameters(nameValuePairs, iso-8859-1));
            writer.close();
            os.close();

            InputStream is = urlConnection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, iso-8859-1));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            urlConnection.disconnect();

            return sb.toString();
        }
        catch (UnknownHostException e) {
            // handle it

            return null;
        }
        catch (Exception e) {
            // this is where I'm always getting a timeout exception
            return null;
        }
    }

    @Override
    protected void onPostExecute(String result)
    {
        progressDialog.dismiss();
    }
}

編集:これは特定のネットワーク通話中にのみ発生したと思っていましたが、さまざまな場所で経験しました.

EDIT 2:これをもう一度見てみると、これが見つかりまし。それが私の問題だと思います。これは、ネットワーク呼び出し用に Android AsyncTask を実装する前は存在しませんでした。AsyncTask が何らかの形でスレッド化を台無しにして、タイムアウトを引き起こしていると思います。

4

2 に答える 2

1

この答えにはあまり満足していませんが、うまくいっているようです。私のコードに問題があるか、HTTPUrlConnection に何らかのバグがあるに違いないと思います。Google が Froyo 以下にバグがあると言っているのは知っていますが、私がテストしている 2.3.4 と 4.2 には奇妙な点が見られます。基本的に、上記のコードを Apache のコードに置き換えましたが、タイムアウトが表示されません。

private static String post(ArrayList<NameValuePair> params){        
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httpreq = new HttpPost("www.url.com");
    httpreq.setEntity(new UrlEncodedFormEntity(params));
    HttpResponse response = httpclient.execute(httpreq);
    HttpEntity entity = response.getEntity();
    InputStream is = entity.getContent();

    BufferedReader reader = new BufferedReader(new InputStreamReader(is, NetworkConstants.HTTP_ACCEPTED_CHARSET), 8);
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
        sb.append(line + "\n");
    }
    is.close();          

    return sb.toString();
}
于 2013-03-10T23:55:01.900 に答える
1

HTTPUrlConnection のタイムアウトを明示的に設定できます。
urlConnection.setConnectionTimeout(aLongerTimeout)

于 2013-03-10T22:53:56.717 に答える