Android-异步任务未按预期更新活动
我有一个按钮,它运行一个异步任务,从web下载一些信息,并将这些信息放入活动中的一个局部变量中,可以通过按另一个按钮查看。 此外,我还更新了UI中的一个视图,以说明同步是否正在运行或准备就绪 出于某种原因,有时onPostExecute不会按预期更新UI和局部变量,尽管有时会这样做。我使用调试器进行了检查,更新变量(handleDownloadComplete)的代码正在运行,但UI和show data按钮仍然没有正确更新。 注意:问题主要发生在连接超时时,但我仍然看到调试器的返回值是正确的——“连接超时”,但活动并没有更新 谢谢 异步任务类:Android-异步任务未按预期更新活动,android,android-asynctask,Android,Android Asynctask,我有一个按钮,它运行一个异步任务,从web下载一些信息,并将这些信息放入活动中的一个局部变量中,可以通过按另一个按钮查看。 此外,我还更新了UI中的一个视图,以说明同步是否正在运行或准备就绪 出于某种原因,有时onPostExecute不会按预期更新UI和局部变量,尽管有时会这样做。我使用调试器进行了检查,更新变量(handleDownloadComplete)的代码正在运行,但UI和show data按钮仍然没有正确更新。 注意:问题主要发生在连接超时时,但我仍然看到调试器的返回值是正确的——
public class DownloadDataTask extends AsyncTask<String, Integer, String> {
public interface DownloadCompleteHandler
{
void handleDownloadComplete(String result);
}
private DownloadCompleteHandler handler;
@Override
protected String doInBackground(String... urls) {
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
@Override
protected void onPostExecute(String result) {
handler.handleDownloadComplete(result);
}
private String downloadUrl(String urlStr) throws IOException
{
InputStream is = null;
String result = new String();
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
int response = conn.getResponseCode();
is = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) {
result += inputLine;
}
}
catch (MalformedURLException ex) {
result = "Malformed URL: " + urlStr;
}
catch (SocketTimeoutException ex) {
result = "Connection timed out";
}
finally {
if (is != null)
is.close();
}
return result;
}
public void setHandler(DownloadCompleteHandler handler) {
this.handler = handler;
}
}
编辑:我注意到我缺少onSaveInstanceState
和onRestoreInstanceState
实现,并认为这可能是原因,因为问题只在连接超时时出现,这可能会导致活动因某种原因重新启动。所以我添加了它们(也在上面的代码中),但问题仍然发生
任何人有什么想法吗?我错了
但我认为这不是连接超时的问题。它可能是当你改变设备的方向。因为当方向改变时,活动将重新创建,并且有一个具有不同textview的新活动对象
但如果是这样的话,那么你应该尝试将android:configChanges=“orientation | keyboardHidden | screenSize”添加到你的mainfest中
这篇文章很好地描述了当前的问题:
已编辑
onSaveInstanceState只保存该活动使用的数据,而不保存视图。将重新创建视图。因为您正在通过downloader.setHandler传递活动的引用(this);因此,下载后,完整的处理程序将指向旧活动而不是新活动,textview将属于旧活动。因此,新活动没有完成下载事件
如果您确定handler.handleDownloadComplete(结果)已完成;正在调用,则这可能是唯一的问题。您必须调用runOnUiThread以正确更新ui线程上的小部件,如下所示:
public void handleDownloadComplete(final String result)
{
runOnUiThread(new Runnable() {
public void run() {
downloadResult = result;
TextView view = (TextView)findViewById(R.id.textWebResult);
view.setText("Ready");
isSyncing = false;
}
});
}
在这种情况下,控制是否会转到handleDownloadComplete()方法。?是的,根据调试器,它是,并且在运行视图的setText()方法后,GUI仍然保持不变。让我们尝试直接在onPostExecute方法中设置textview,而不使用接口。告诉我结果。同样的事情。。。为什么这很重要?这只是一个函数调用,而不是另一个线程…顺便说一句,它只在连接超时时发生。如果连接成功,它就永远不会发生。所以可能是等待15秒的结果…我想可能是这样,但我试着确保手机在整个过程中保持相同的方向,问题仍然出现。。。不管怎样,我还是要试试。好吧,这肯定和这个有关。你能再解释一下吗?既然我将信息保存在onSaveInstanceState中,为什么这不起作用?如果可以的话,我不想覆盖配置更改。事实并非如此,因为AsyncTask的onPostExecute()总是在UI线程上执行。您是否尝试将对handler.handleDownloadComplete(result)的调用从postExecute移动到downloadUrl方法?上述代码也是必需的。当超时发生时,postExecute可能由于某种原因没有调用。postExecute正在调用,我可以在调试器中看到它。我一个接一个地跟踪这些命令,发现当我运行updateview命令时,UI中什么都没有发生。
public void handleDownloadComplete(final String result)
{
runOnUiThread(new Runnable() {
public void run() {
downloadResult = result;
TextView view = (TextView)findViewById(R.id.textWebResult);
view.setText("Ready");
isSyncing = false;
}
});
}