Ich parse XML-Daten und füge sie in ein Objekt ein. Dies dauert ziemlich lange, und ich habe beschlossen, es im Hintergrund mit AsyncTask laufen zu lassen. Mein Code ist fast genau wie dieses Beispiel: Wie erhält man XML mit AsyncTask und Timer?
Der Unterschied besteht darin, dass ich PublishProgress so lange wie möglich nutzen möchte. Der relevante Teil des Codes, in dem ich den Fortschritt veröffentlichen möchte:
@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;
}
}
Sie haben sicher schon gemerkt, dass ich ein Anfänger bin. Die Forschung, die dem, was ich tun möchte, am nächsten kommt, lautet:
http://www.mail-archive.com/Android-developers@googlegroups.com/msg79275.html
Ja, das ist ein bisschen komplexer... Zwei Ansätze:
1) AsyncTask implementieren org.sax.ContentHandler implementieren. Auf diese Weise haben die SAX-Callbacks einen direkten Zugriff auf AsyncTask.publishProgress().
2) Erstellen Sie einen Delegaten, so dass die Parser ein Handle zurück zu AsyncTask hat für die Buchung von Fortschrittsaktualisierungen hat.
Wenn ich das oben genannte versuche, erhalte ich:
Die Methode publishProgress(Progress...) vom Typ AsyncTask ist nicht sichtbar
Leider, wie kann ich publicProgress von endElement aufrufen? Oder könnte mir jemand einen Tipp geben, wie man das richtig macht? Um zu rekapitulieren:
Ich habe XML-Daten. Das Lesen der Daten ist ein langer Vorgang. Ich verwende den SAXParser, um die Daten zu erhalten. Bei der endElement-Methode werden die Daten zu einem Objekt hinzugefügt, das schließlich an anderer Stelle verwendet wird. Die meisten Recherchen haben ergeben, dass ich AsyncTask verwenden muss, und ich verwende das jetzt, weil ich ein gutes Beispiel von Commonsware für die Bildschirmrotation habe. Die Frage ist, wie ich den Fortschritt aktualisieren kann, während ich weitermache.
Bearbeiten: @Cristian hier ist die asynchrone Aufgabe:
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);
}
}
Dies ist fast ein exaktes Duplikat dieses Commonsware-Beispiels: https://github.com/commonsguy/cw-Android/blob/master/Rotation/RotationAsync/src/com/commonsware/Android/rotation/async/RotationAsync.java
Wie Sie sehen können:
saxClientsHandler = neu SaxClientsHandler();
ruft den SaxClientHandler() auf, wo die endElement-Methode existiert. Ich versuche, den Fortschritt von dort aus zu veröffentlichen.
@Mayra, schlagen Sie vor, dass ich den gesamten saxClientHandler-Code in die AsyncTask migriere?