【发布时间】:2015-05-15 21:29:03
【问题描述】:
对于我的项目,我需要检查一个 URL 以查看它是否存在。
所以我创建了一个HttpURLConnection 并连接到 url 并等待响应代码。
由于我不能在我的主线程中使用那个 HttpURLConnection,我不得不将它移动到一个 AsyncTask 并让它在一个单独的线程上运行。
这就是我的 AsyncTask 代码的样子(仅重要部分):
private class URLExists extends AsyncTask<String, Void, Boolean> {
protected Boolean doInBackground(String... urls)
{
boolean isValid = false;
try
{
URL myurl = new URL(urls[0]);
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection connection = (HttpURLConnection) myurl.openConnection();
connection.setUseCaches(true);
connection.setRequestMethod("HEAD");
connection.connect();
int code = connection.getResponseCode();
...
connection.disconnect();
if(code != 404)
isValid = true;
else
isValid = false;
}
...
return isValid;
}
protected void onPostExecute(Boolean isValid)
{
isTrue = isValid;
}
}
所以基本上我会得到一个布尔值isTrue,它告诉我网址是否有效。当我运行它时,我得到了正确的结果,一切正常。
但是现在,当我执行这个 AsyncTask 时,它显然与我的主线程并行运行。
我有这个代码:
new URLExists().execute("https://www.example.com");
if(isTrue)
{
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Do Something
}
});
}
由于我的 AsyncTask 并行运行,我的主线程执行下一个操作而不等待 AsyncTask 的结果。因为isTrue默认是false,所以if语句永远不会运行。
我当然知道 AsyncTask 中的 protected void onPostExecute(),但这是否意味着我的主线程中的所有代码都必须在并行线程中的那个函数中?这一切都取决于 URL 检查的结果。
我知道 .get() 方法,但这会冻结我的 MainThread 和 UI,所以这对我来说不是一个真正的选择。
还有其他方法可以让主线程等待 AsyncTask 吗?我知道 AsyncTask 的目的是失败的,但我只想检查 URL 是否存在,我只能在 AsyncTask 中进行检查。
【问题讨论】:
-
不建议等待主线程,并将其视为不良用户体验。您可以将有关设置单击侦听器的代码移动到
AsyncTask的onpostexecute。但是,您应该以某种方式让用户知道该按钮将无法按预期工作。我会禁用它,直到我从网络得到答案,或者推迟点击执行,直到我从网络得到答案。更多关于你 asynctask 的 cmets。 404 不仅是一种错误响应代码,而且许多网络服务器也无法正确处理 HEAD 请求。所以请注意这些事实 -
非常感谢您的回答!
标签: java android android-asynctask httpurlconnection