2011-02-10 2 views
3

Я разбираю XML-данные и помещаю их в объект. Это занимает довольно много времени, и я решил запустить его в фоновом режиме с помощью AsyncTask. Мой код почти такой же, как в этом примере: How to get XML using AsyncTask and Timer?Как получить 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 реализовать орг. sax.ContentHandler. Таким образом, обратные вызовы SAX имеют прямой доступ к AsyncTask.publishProgress().

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

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

Метод publishProgress (Прогресс ...) от типа AsyncTask является не видно

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

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

Edit: @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 = new SaxClientsHandler();

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

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

+0

Вставьте задание async, которое вы используете, и как вы пытаетесь вызвать метод publishProgress. – Cristian

ответ

1

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

+2

Спасибо, Майра! Ключ должен был скопировать код SaxClientsHandler() в RotationAwareTask, как вы предложили. Я не знал, что вы можете вложить такие классы. На самом деле я даже не знал, с чего начать, и я боролся с этим, по крайней мере, неделю. –