Потенциальная ошибка в асинктаск Android - PullRequest
0 голосов
/ 13 декабря 2010

Я занимаюсь разработкой простого приложения для Android и только что попытался переключиться на использование асинхронной задачи для вызова FTP и синтаксического анализа XML, который требуется приложению (это приложение с погодой).

К сожалению, яначал замечать очень странное поведение в моем приложении.Я отладил и обнаружил, к моему ужасу, что код внутри метода doInBackground () выполнялся не по порядку!

Приведенный ниже код упрощен (операторы catch свернуты и т. Д.) Для краткости, однако ни одно из основныхизменилось.Asynctask вызывается в onResume (), и затем он вызывает сервер ftp, загружает файл и затем анализирует его.Что происходит (что я очень четко вижу по операторам отладки, которые вы видите ниже), так это то, что вызов синтаксического анализа выполняется до завершения загрузки файла.Таким образом, с точки зрения операторов отладки, порядок часто:

  1. До получения файла
  2. До анализа файла
  3. После анализа файла с ошибкой (как файлеще не загрузил!)
  4. После получения файла

Я более чем рад предоставить больше кода (все это при необходимости!) и ответить на любые вопросы, которые могут возникнуть у любого.

    @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);
        }
    }

Редактировать: причина, по которой я обнаружил, что она выполнялась не по порядку, заключалась в том, что начали возникать странные ошибки.Если я запускаю все в основном потоке пользовательского интерфейса, это работает, однако, как только я помещаю все это в асинхронную задачу, я получаю ошибки синтаксического анализа XML.Кажется, проблема в том, что файл не загружен полностью, когда мое приложение пытается его проанализировать.

Ответы [ 2 ]

1 голос
/ 13 декабря 2010

Вы, вероятно, в итоге запустили более одного потока.Вы видите журнал разбора от предыдущего, заканчивающегося, и затем новый загружает загрузку.Поскольку вы, вероятно, хотите использовать только по одному, вам нужно использовать какую-то блокировку, чтобы предотвратить одновременное выполнение двух.

0 голосов
/ 29 октября 2011
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.

Для получения дополнительной информации см. Документ.

Привет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...