如何使用AsyncTask和PublishProgress获取XML

时间:2011-02-10 19:20:01

标签: android xml multithreading saxparser android-asynctask

我解析XML数据并将其放入对象中。这需要相当长的时间,我决定使用AsyncTask在后台运行它。我的代码几乎与此示例完全相同: How to get XML using AsyncTask and Timer?

不同之处在于我想要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/android-developers@googlegroups.com/msg79275.html

  

是的,这有点复杂......两个   接近:

     

1)实现AsyncTask   org.sax.ContentHandler。那样的   SAX回调可以直接访问   AsyncTask.publishProgress()。

     

2)创建一个委托以便   解析器有一个回到AsyncTask的句柄   用于发布进度更新。

当我尝试上述内容时,我得到了:

  

方法   publishProgress(Progress ...)来自   类型AsyncTask是   不可见

唉,我如何从endElement调用publicProgress?或者有人可以给我一些如何正确地做到这一点?回顾一下:

我有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 = new   SaxClientsHandler();

调用存在endElement方法的SaxClientHandler()。我试图从那里公布进展情况。

@Mayra,您是否建议我将所有saxClientHandler代码迁移到AsyncTask中?

1 个答案:

答案 0 :(得分:1)

您正在执行RotationAwareTask.publishProgress(); publishProgress不是静态方法,您需要在RotationAwareTask的实例上调用它。