How to get XML using AsyncTask and PublishProgress

3k Views Asked by At

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/[email protected]/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?

1

There are 1 best solutions below

1
On BEST ANSWER

You are doing RotationAwareTask.publishProgress(); publishProgress is not a static method, you need to call it on the instance of RotationAwareTask.