0

(为清楚起见进行了更新)我可能需要根据返回的结果在 Android AsyncTask 中重新运行 HTTP 请求。我在下面粘贴了一个异步任务的简单示例。我不会取回错误代码,而是取回一个临时工作 ID,告诉我服务器正在处理我的请求。我需要每隔几秒钟检查一次并向服务器发送工作 ID,直到它完成并给我我的数据。就是这样!听起来很简单,但我似乎无法弄清楚:

private class HttpGetter extends AsyncTask<URL, Void, Void> {

    @Override
    protected Void doInBackground(URL... urls) {
        // TODO Auto-generated method stub
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(urls[0]);

        try {
            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();

            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
                Log.v("Getter", "Your data: " + builder.toString()); // response
                                                                     // data
            } else {
                Log.e("Getter", "Failed to download file");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

然后使用 AsyncTask:

HttpGetter get = new HttpGetter();
get.execute("http://www.google.es");
4

2 回答 2

2

这是您的改进版本,Getter AsyncTask它获取您的“工作 id”并使用它来轮询 HTTPd,直到有东西回来。
您至少需要修改标有TODO注释的部分以满足您的需要。

private class HttpGetter extends AsyncTask<String, Void, Void> {

    private String parseWorkingId(String responseData) {
        // TODO: implement me: parse json/xml/whatever
        return responseData;
    }

    private String getWorkingId(HttpClient client, String url) throws IOException {
        StringBuilder builder = new StringBuilder();
        HttpGet httpGet = new HttpGet(url);

        HttpResponse response = client.execute(httpGet);
        StatusLine statusLine = response.getStatusLine();
        int statusCode = statusLine.getStatusCode();

        if (statusCode == 200) {
            HttpEntity entity = response.getEntity();
            InputStream content = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(content));
            String line;
            while ((line = reader.readLine()) != null) {
                // don't forget to add the stripped line ending
                builder.append(line).append("\n");
            }
            String responseData = builder.toString();
            Log.v("Getter", "Your data: " + responseData);
            return parseWorkingId(responseData);
        } else {
            Log.e("Getter", "Failed to download file");
            throw new IOException("download failed");
        }
    }

    private String getData(HttpClient client, String url, String workingId) throws IOException {
        // TODO is result data a String? maybe you want to use a Stream
        StringBuilder builder = new StringBuilder();
        // TODO change me to something matching your needs
        HttpGet httpGet = new HttpGet(url + "?workingId=" + Uri.encode(workingId));

        HttpResponse response = client.execute(httpGet);
        StatusLine statusLine = response.getStatusLine();
        int statusCode = statusLine.getStatusCode();

        if (statusCode == 200) {
            HttpEntity entity = response.getEntity();
            InputStream content = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(content));
            String line;
            while ((line = reader.readLine()) != null) {
                // don't forget to add the stripped line ending
                builder.append(line).append("\n");
            }
            String responseData = builder.toString();
            if (responseData.length() > 0) {
                Log.v("Getter", "Your data: " + responseData);
                return responseData;
            } else {
                Log.v("Getter", "nothing here yet");
                return null;
            }
        } else {
            Log.e("Getter", "Failed to download file");
            return null;
        }
    }

    @Override
    protected Void doInBackground(String... urls) {
        String url = urls[0];
        HttpClient client = new DefaultHttpClient();
        String data = null;

        try {
            // get working id
            String workingId = getWorkingId(client, url);

            // loop for getting data
            while (true) { // TODO add timeout or some other sane break condition
                data = getData(client, url, workingId);
                if (data == null) {
                    try {
                        Thread.sleep(10 * 1000); // 10s
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    break;
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (data != null) {
            // TODO do something with data
            Log.v("Getter", "here is your data: " + data);
        }

        // maybe you want to return data to onPostExecute()
        return null;
    }
}
于 2013-09-24T11:43:28.023 回答
0

事实上你的代码可以运行良好,但仍有一些地方可以改进。

  1. 需要终止。循环几次后,它应该被终止。

  2. 错误处理。当一些http异常引发时,无论是继续运行还是中断。

  3. 睡觉时间。在每次迭代中将睡眠时间加倍。

PS:这里还有一个bug,可能你只是忘记包含进去了。

String status = jsonObject.getString("status").toString();

这条线也应该放在循环内。

于 2013-09-04T03:15:49.397 回答