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.