如何使用 AsyncTask 和 PublishProgress 获取 XML

发布于 2024-10-16 14:26:07 字数 4043 浏览 7 评论 0原文

我解析 XML 数据并将其放入一个对象中。这需要相当长的时间,我决定使用 AsyncTask 在后台运行它。我的代码几乎与这个例子一模一样: 如何使用 AsyncTask 和 Timer 获取 XML?

区别在于我想在做多时发布进度。我想发布进度的代码的相关部分:

@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/[电子邮件受保护]/msg79275.html

是的,这有点复杂......两个 方法:

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

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

当我尝试上述操作时,我得到:

方法 发布进度(进度...) 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 = 新 SaxClientsHandler();

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人间☆小暴躁 2024-10-23 14:26:07

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文