I parse XML data and put it into an object. This takes fairly long and I have decided to run it in the background using AsyncTask. My code is almost exactly like this example:
How to get XML using AsyncTask and Timer?
The difference being that I want to PublishProgress as I go long. The relevant part of the code where I want to publish progress:
@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;
}
}
By now you would have deduced that I am a novice. The closest research that matches what I want to do states:
http://www.mail-archive.com/android-developers@googlegroups.com/msg79275.html
Yes, that is a bit more complex… Two
approaches:1) Make AsyncTask implement
org.sax.ContentHandler. That way the
SAX callbacks have direct access to
AsyncTask.publishProgress().2) Create a delegate so that the
parser has a handle back to AsyncTask
for posting progress updates.
When I try the above I get:
The method
publishProgress(Progress…) from the
type AsyncTask is
not visible
Alas, how can I call publicProgress from endElement? Or could someone give me some how to do this properly? To recap:
I have XML data.
Reading the data is a long operation.
I use the SAXParser to get the data.
On the endElement method the data is added to an object which will eventually be used elsewhere.
Most research indicates I have to use AsyncTask and I am using that now because I have a good example from Commonsware for screen rotation.
The question is how to update progress as I go along.
Edit:
@Cristian here is the async task:
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);
}
}
This is almost an exact duplicate of this Commonsware example:
https://github.com/commonsguy/cw-android/blob/master/Rotation/RotationAsync/src/com/commonsware/android/rotation/async/RotationAsync.java
As you can see:
saxClientsHandler = new
SaxClientsHandler();
calls the SaxClientHandler() where the endElement method exists. I am trying to publish the progress from there.
@Mayra, are you suggesting that I migrate all the saxClientHandler code into the AsyncTask?
You are doing
RotationAwareTask.publishProgress();publishProgressis not a static method, you need to call it on the instance ofRotationAwareTask.