AsyncTask从onPostExecute检索数据

时间:2018-02-08 01:44:03

标签: android multithreading android-asynctask download

我写了一个小类来从URL下载数据。

下载程序类:

public class HTTPHelper extends AsyncTask<String, Void, String> {

    private OnHTTPCompleted listener;

    HTTPHelper(OnHTTPCompleted l){
        listener = l;
    }

    private String readStream(InputStream is) {
        try {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            int i = is.read();
            while (i != -1) {
                bo.write(i);
                i = is.read();
            }
            return bo.toString();
        } catch (IOException e) {
            return "";
        }
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            URL url = new URL(params[0]);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            try {
                InputStream in = new BufferedInputStream(urlConnection.getInputStream());
                return readStream(in);
            } finally {
                urlConnection.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        try {
            listener.onHttpCompleted(s);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

接口类:

public interface OnHTTPCompleted {
    void onHttpCompleted(Object o);
}

我们希望下载是异步的,因此我们决定使用AsyncTask。我们希望在下载完成后从HTTP类返回数据,但是:不直接在onPostExecute方法中更新UI元素。

我们只想返回原始数据而无需进一步处理。 我们能够找到的所有其他解决方案直接使用onPostExecute方法中的下载数据来更新一些UI元素等。

另外值得一提的是:task.get()不是一个选项,因为它阻止了主线程。

1 个答案:

答案 0 :(得分:2)

根据问题和问题的评论,我已经理解了您的问题,您正在尝试使用AsyncTask作为库函数,它将为您完成下载工作。您不希望使用AsyncTask中的下载资料处理任何进一步处理。你想稍后在调用类中处理它们,这很好。

如果我理解正确,那么你几乎就在那里。您只需在AsyncTask中更改一些声明即可。让我在这里重新编写你的AsyncTask,并在其中进行一些编辑。

public class HTTPHelper extends AsyncTask<String, Void, ByteArrayOutputStream> {

    private OnHTTPCompleted listener;

    HTTPHelper(OnHTTPCompleted l){
        listener = l;
    }

    private ByteArrayOutputStream readStream(InputStream is) {
        try {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            int i = is.read();
            while (i != -1) {
                bo.write(i);
                i = is.read();
            }
        } catch (IOException e) {
            return null;
        }
    }

    @Override
    protected ByteArrayOutputStream doInBackground(String... params) {
        try {
            URL url = new URL(params[0]);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            try {
                InputStream in = new BufferedInputStream(urlConnection.getInputStream());
                return readStream(in);
            } finally {
                urlConnection.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(ByteArrayOutputStream s) {
        super.onPostExecute(s);
        try {
            listener.onHttpCompleted(s);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

由于您希望在不进行进一步处理的情况下返回原始数据,因此必须将ByteArrayOutputStream返回到调用UI线程,而不将其转换为String对象。希望有所帮助!