作为AsyncTask的一部分重新运行HTTP请求

时间:2013-09-04 03:02:01

标签: android android-asynctask

(为了清楚起见而更新)我可能需要根据我得到的结果在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");

2 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:0)

事实上,您的代码可以正常运行,但仍有一些地方可以改进。

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

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

  3. 睡眠时间。每次迭代加倍睡眠时间。

  4. PS:这里也有一个错误,也许你只是忘了加入。

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

    这一行也应该放在循环中。