【发布时间】: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