简体   繁体   中英

Android parsing of data very slow

I'm trying to make an app that parses an RSS feed. I run my app but the fetching of data is very slow although the source link ( http://api.androidhive.info/music/music.xml ) is very fast.

I need my app to respond quickly.

My app code :

package com.sta.map;

import java.util.ArrayList;
import java.util.HashMap;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;


import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.TextView;

public class POSTS extends Activity {
    static final String KEY_ARTIST = "artist";
    static final String KEY_THUMB_URL = "thumb_url";

    ListView list;
    WbAdapter adapter;

    static String URL = "http://api.androidhive.info/music/music.xml";

    ProgressDialog pDialog;

    ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.posts);

        new ParseXMLTask().execute();
    }

    class ParseXMLTask extends AsyncTask<String, String, String> {
        protected void onPreExecute() {
            // Showing progress dialog before sending http request
            pDialog = new ProgressDialog(POSTS.this);
            pDialog.setMessage("Please wait..");
            pDialog.setIndeterminate(true);
            pDialog.setCancelable(false);
            pDialog.show();
        }
        @Override
        protected String doInBackground(String... unused) {
           XMLParser parser = new XMLParser();
           String xml = parser.getXmlFromUrl(url); // getting XML from URL
            return xml;
        }

        @Override
        protected void onPostExecute(String result) {
            pDialog.dismiss();
            XMLParser parser = new XMLParser();
            Document doc = parser.getDomElement(result); // getting DOM element

            NodeList nl = doc.getElementsByTagName("song");
            // looping through all song nodes <song>
            for (int i = 0; i < nl.getLength(); i++) {
                // creating new HashMap
                HashMap<String, String> map = new HashMap<String, String>();
                Element e = (Element) nl.item(i);
                // adding each child node to HashMap key => value
                map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
                map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));

                // adding HashList to ArrayList
                songsList.add(map);
            }

            list=(ListView)findViewById(R.id.list);
            adapter= new WbAdapter(POSTS.this, songsList);        
            list.setAdapter(adapter);
        }   
    }
}

XMLParser class :

package com.sta.map;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

public class XMLParser {

    // constructor
    public XMLParser() {

    }

    /**
     * Getting XML from URL making HTTP request
     * @param url string
     * */
    public String getXmlFromUrl(String url) {
        String xml = null;

        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            xml = EntityUtils.toString(httpEntity);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // return XML
        return xml;
    }

    /**
     * Getting XML DOM element
     * @param XML string
     * */
    public Document getDomElement(String xml){
        Document doc = null;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {

            DocumentBuilder db = dbf.newDocumentBuilder();

            InputSource is = new InputSource();
                is.setCharacterStream(new StringReader(xml));
                doc = db.parse(is); 

            } catch (ParserConfigurationException e) {
                Log.e("Error: ", e.getMessage());
                return null;
            } catch (SAXException e) {
                Log.e("Error: ", e.getMessage());
                return null;
            } catch (IOException e) {
                Log.e("Error: ", e.getMessage());
                return null;
            }

            return doc;
    }

    /** Getting node value
      * @param elem element
      */
     public final String getElementValue( Node elem ) {
         Node child;
         if( elem != null){
             if (elem.hasChildNodes()){
                 for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
                     if( child.getNodeType() == Node.TEXT_NODE  ){
                         return child.getNodeValue();
                     }
                 }
             }
         }
         return "";
     }

     /**
      * Getting node value
      * @param Element node
      * @param key string
      * */
     public String getValue(Element item, String str) {     
            NodeList n = item.getElementsByTagName(str);        
            return this.getElementValue(n.item(0));
        }
}

EDIT 1: In the manifest I found this code :

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="16" />

I remove this part android:targetSdkVersion="16" and the parsing become very fast

Why ??

I found that on large files the performance of the XMLParser is very poor and very memory hungry. Specifically if one node in xml is very large, like an encoded bitmap. Think about it it has to load the entire string into memory at one time. I switched to parsing the file myself since I was only looking for one specific section and reading the data using a BufferedInputStream to avoid the memory spike.

This may not be your problem, but know that for very large files the XMLParser is not usable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM