我正在为Android开发一个简单的应用程序,并且刚刚尝试切换到使用asynctask来进行应用程序所需的FTP调用和XML解析(这是一个天气应用程序FYI)。
不幸的是,我开始注意到我的应用中出现了非常奇怪的行为。我调试了,并且惊恐地发现doInBackground()方法中的代码执行不正常!
为简洁起见,下面的代码已经过简化(catch语句汇总了),但没有任何必需品发生变化。在onResume()中调用asynctask,然后调用ftp服务器,下载文件,然后解析它。正在发生的事情(我可以通过下面的调试语句清楚地看到),是在文件下载完成之前进行的解析调用。因此,就调试语句而言,顺序通常是:
我非常乐意提供更多代码(如果需要,还可以提供所有代码!),并回答任何人可能提出的任何问题。
@Override
public void onResume()
{
if(!inOnResume)
{
inOnResume = true;
super.onResume();
File file = new File(getFilesDir(), selectedCity);
new GetBOMWeatherData().execute(file);
}
}
private class GetBOMWeatherData extends AsyncTask<File, Void, Void>
{
boolean fileDownloaded = false;
@Override
protected void onPreExecute()
{
showDialog(PROGRESS_KEY);
super.onPreExecute();
}
@Override
protected Void doInBackground(File... params)
{
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(params[0]);
}
catch (FileNotFoundException e)
{
Log.e("ApiException", "There was an error opening the file output stream.", e);
cancel(false);
}
try
{
Log.d("Before get file", "Before get file");
DataRetriever.getPageContent(selectedCity, fos);
Log.d("After get file", "After get file");
fileDownloaded = true;
}
catch (ApiException e)
{
Log.d("After get file with error", "After get file with error");
Log.e("ApiException", "There was an error opening the file output stream.", e);
cancel(false);
}
finally
{
Log.d("After get file finally", "After get file finally");
}
try
{
Log.d("Before parse file", "Before parse file");
forecasts = parseXML(selectedCity);
Log.d("After parse file", "After parse file");
lastDownloaded.put(selectedCity, new Date());
}
catch (FactoryConfigurationError e)
{
Log.d("After parse file with error", "After parse file with error");
Log.e("XMLParsingException", "There was an error in the factory configuration.", e);
cancel(false);
}
finally
{
Log.d("After parse file finally", "After parse file finally");
}
return null;
}
@Override
protected void onPostExecute(Void file)
{
inOnResume = false;
super.onPostExecute(file);
dismissDialog(PROGRESS_KEY);
updateView();
}
@Override
protected void onCancelled()
{
super.onCancelled();
showDialog(FAILURE_KEY);
}
}
编辑:我发现它无序执行的原因是奇怪的错误开始发生。如果我在主UI线程中运行它可以正常工作,但是只要我把它全部放在asynctask中我就会得到XML解析错误。问题似乎是当我的应用尝试解析文件时,文件未完全下载。
答案 0 :(得分:1)
你最终可能会运行多个线程。您将看到前一个解析日志完成,然后新的解析日志正在进入下载。由于您可能一次只需要一个,因此您需要使用某种锁定来防止两个同时运行。
答案 1 :(得分:0)
DataRetriever.getPageContent(selectedCity, fos);
这是在另一个线程中执行的,它没有阻塞。所以它在这里崩溃并且不在主线程中完全正常。不要使用它。
SAXParser parseur = SAXParserFactory.newInstance().newSAXParser();
parseur.parse(uri, DefaultHandler);
// On récupère directement la liste des feeds
ArrayList<Object> entries = ((DefaultHandler) handler).getData();
当然,这只是在您不将XML文件保存到内存中时。然后你只需要在实现DefaultHandler的类中进行解析。
有关详细信息,请参阅doc。
此致