【问题标题】:AsyncTask retrieve data from onPostExecute [closed]AsyncTask 从 onPostExecute 检索数据 [关闭]
【发布时间】:2018-02-08 01:44:03
【问题描述】:

我写了一个小类来从 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() 不是一个选项,因为它阻塞了主线程。

【问题讨论】:

  • 到底是什么问题?也就是说,您发布的代码究竟是如何无法按您想要的那样工作的?
  • @MikeM。下载器确实可以工作,但是 AsyncTask 是一个封闭系统,我们无法从 AsyncTask 类中检索任何结果。我们只能插入带有接口的代码。基本上我们可以将数据放入 AsyncTask 类,但不能从中获取任何数据。 (希望你能跟上)
  • 我不确定您所说的“我们只能插入带有接口的代码”是什么意思。接口是您在调用对象中获得结果的方式。 onHttpCompleted() 方法将从onPostExecute() 运行,Object o 参数将是数据。如果您向我们展示您是如何创建和执行AsyncTask 并解释您在该上下文中遇到的问题,它可能会更好地说明您的问题。
  • 谁/什么将使用这些数据? onPostExecute() 方法是使用来自异步调用的数据的自然场所,因为一旦该任务完成,它本身就会被调用。
  • 是的,我们知道这一点,但这需要我们与应该与之隔离的类中的 UI 元素进行交互。助手应该只下载数据并返回它,数据的更新/使用应该在一个单独的类中执行。因此,据我们了解,在下载器类中与 UI 交互将是一个设计问题。 @TimBiegeleisen

标签: android multithreading android-asynctask download


【解决方案1】:

据我根据问题和问题下的 cmets 了解您的问题,您正在尝试使用 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 对象。希望有帮助!

【讨论】:

  • 我认为您错过了问题下方的最终 cmets。看来这不是 OP 所说的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
相关资源
最近更新 更多