Как получить XML с помощью AsyncTask и PublishProgress

Я анализирую XML-данные и помещаю их в объект. Это занимает довольно много времени, и я решил запустить его в фоновом режиме с помощью AsyncTask. Мой код почти такой же, как в этом примере: Как получить XML с помощью AsyncTask и Таймер?

Разница в том, что я хочу PublishProgress, когда я иду в длинную позицию. Соответствующая часть кода, где я хочу опубликовать прогресс:

@Override   
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {       
        if (localName.equalsIgnoreCase("client")) {         
            clients.addClient(mClient);
            // Publish Progress
            RotationAwareTask.publishProgress();
            mClient = null;
        }       
    }

К настоящему времени вы бы сделали вывод, что я новичок. Ближайшее исследование, которое соответствует тому, что я хочу сделать, гласит:

http://www.mail-archive.com/[email protected]/msg79275.html

Да, это немного сложнее... Два подхода:

1) Заставьте AsyncTask реализовать org.sax.ContentHandler. Таким образом, обратные вызовы SAX имеют прямой доступ к AsyncTask.publishProgress().

2) Создайте делегата, чтобы синтаксический анализатор имел дескриптор AsyncTask для публикации обновлений хода выполнения.

Когда я пытаюсь сделать выше, я получаю:

Метод publishProgress(Progress...) из типа AsyncTask не виден

Увы, как мне вызвать publicProgress из endElement? Или может кто-нибудь дать мне, как это сделать правильно? Резюме:

У меня есть XML-данные. Чтение данных — долгая операция. Я использую SAXParser для получения данных. В методе endElement данные добавляются к объекту, который в конечном итоге будет использоваться в другом месте. Большинство исследований показывают, что я должен использовать AsyncTask, и я использую его сейчас, потому что у меня есть хороший пример от Commonsware для поворота экрана. Вопрос в том, как обновлять прогресс по мере продвижения.

Изменить: @Cristian вот асинхронная задача:

static class RotationAwareTask extends AsyncTask<Void, Void, Void> {        
        RotationAsync activity = null;      
        int progress = 0;       

        private SaxClientsHandler saxClientsHandler;

        RotationAwareTask(RotationAsync activity) {
            attach(activity);
        }

            @Override
        protected Void doInBackground(Void... unused) {         
            try {
                SAXParserFactory spf = SAXParserFactory.newInstance();
                SAXParser sp = spf.newSAXParser();
                XMLReader xr = sp.getXMLReader();
                saxClientsHandler = new SaxClientsHandler();
                xr.setContentHandler(saxClientsHandler);
                InputSource mSource = new InputSource( new StringReader( Whmcs.getClientsXml() ) );
                xr.parse(mSource);          
            } catch (Exception e) {
                Log.e(TAG, e.getMessage(), e);
            }           
            return(null);       
        }

        @Override
        protected void onProgressUpdate(Void... unused) {
            if (activity==null) {
                Log.w("RotationAsync", "onProgressUpdate() skipped – no activity");
            }
            else {
                progress += 5;
                activity.updateProgress(progress);
            }
        }

        @Override
        protected void onPostExecute(Void unused) {
            if (activity == null) {
                Log.w("RotationAsync", "onPostExecute() skipped – no activity");
            }
            else {
                activity.markAsDone();
            }
        }

        void detach() {
            activity = null;
        }

        void attach(RotationAsync activity) {
            this.activity = activity;
        }

        int getProgress() {         
            return(progress);
        }

    }

Это почти точная копия этого примера Commonsware: https://github.com/commonsguy/cw-android/blob/master/Rotation/RotationAsync/src/com/commonsware/android/rotation/async/RotationAsync.java

Как вы видете:

saxClientsHandler = новый SaxClientsHandler();

вызывает SaxClientHandler(), где существует метод endElement. Я пытаюсь опубликовать прогресс оттуда.

@Mayra, вы предлагаете мне перенести весь код saxClientHandler в AsyncTask?


person Eugene van der Merwe    schedule 10.02.2011    source источник
comment
Вставьте асинхронную задачу, которую вы используете, и то, как вы пытаетесь вызвать метод publishProgress.   -  person Cristian    schedule 10.02.2011


Ответы (1)


Вы делаете RotationAwareTask.publishProgress(); publishProgress не статический метод, вам нужно вызвать его на экземпляре RotationAwareTask.

person Cheryl Simon    schedule 10.02.2011
comment
Спасибо, Майра! Ключ был в том, чтобы скопировать код SaxClientsHandler() в RotationAwareTask, как вы предложили. Я не знал, что вы можете вкладывать такие классы. На самом деле я даже не знал, с чего начать поиск, и боролся с этим уже как минимум неделю. - person Eugene van der Merwe; 10.02.2011