Sergiu Mogan
Sergiu Mogan

Reputation: 31

How to use AsyncTask with xml Sax Parser?

I used xml sax parser to read xml from web and it works within android 2.3. But now I want it to work on Android 3.0 to. Because I read the file in the main thread I get the error:

android.os.NetworkOnMainThreadException

I tried to use AsyncTask but I could not make it to work. Please tell me how to implement AsyncTask in my case. Here is my original code:

ListView lw = (ListView)findViewById(R.id.listView1);
final ArrayList<String> list = new ArrayList<String>();
final ArrayAdapter<String> aa = new ArrayAdapter<String>(this,      android.R.layout.simple_list_item_1, list);
lw.setAdapter(aa);

try {
        /* Create a URL we want to load some xml-data from. */
        URL url = new URL("http://www.bnr.ro/nbrfxrates.xml");
        //aded to verify link
        URI uri = new URI(url.toString());
        HttpGet httpget = new HttpGet(uri);
        DefaultHttpClient httpclient = new DefaultHttpClient();
        HttpResponse response = httpclient.execute(httpget);
        if (response.getStatusLine().getStatusCode()==200) {
           url = new URL("http://www.visual-efx.net/nbrfxrates.xml");
        }
        //aded to verify link
        /* Get a SAXParser from the SAXPArserFactory. */
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();

        /* Get the XMLReader of the SAXParser we created. */
        XMLReader xr = sp.getXMLReader();
        /* Create a new ContentHandler and apply it to the XML-Reader*/
        ExampleHandler myExampleHandler = new ExampleHandler();
        xr.setContentHandler(myExampleHandler);

        /* Parse the xml-data from our URL. */
        xr.parse(new InputSource(url.openStream()));
        /* Parsing has finished. */

        for (int i=1; i<=31; i++){
           list.add(myExampleHandler.valuta[i] + " = " + myExampleHandler.pret[i] + " lei");
           aa.notifyDataSetChanged();
        }

} catch (Exception e) {
        /* Display any Error to the GUI. */
        Log.e(MY_DEBUG_TAG, "Error", e);
}

Upvotes: 2

Views: 2420

Answers (1)

Kurtis Nusbaum
Kurtis Nusbaum

Reputation: 30825

You should actually use an AsyncTaskLoader in this case. It'll make things easier. Just create your own class that extends AsyncTaskLoader and just have it have a single method, loadInBackground(). In your loadInBackground() method, put the code that you use to parse the xml like this:

public List<String> loadInBackground(){
  ArrayList toReturn = new ArrayList<String>();

  try {
    URL url = new URL("http://www.bnr.ro/nbrfxrates.xml");

    URI uri = new URI(url.toString());
    HttpGet httpget = new HttpGet(uri);
    DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpResponse response = httpclient.execute(httpget);
    if (response.getStatusLine().getStatusCode()==200) {
       url = new URL("http://www.visual-efx.net/nbrfxrates.xml")
    }
    SAXParserFactory spf = SAXParserFactory.newInstance();
    SAXParser sp = spf.newSAXParser();


    XMLReader xr = sp.getXMLReader();

    ExampleHandler myExampleHandler = new ExampleHandler();
    xr.setContentHandler(myExampleHandler);


    xr.parse(new InputSource(url.openStream()));


    for (int i=1; i<=31; i++){
      toReturn.add(myExampleHandler.valuta[i] + " = " + myExampleHandler.pret[i] + " lei");
    }

  } catch (Exception e) {

    Log.e(MY_DEBUG_TAG, "Error", e);
  }

  return toReturn;
}

Then, in the activity where you're displaying the list, have your Activity implement the LoaderManager.LoaderCallbacks interface, like this

public YourActivity implements LoaderManager.LoaderCallbacks<List<String>>

Then implement the callback methods. For instance, your onLoadFinished() method would look simply like this:

public void onLoadFinished(Loader<List<String>>, List<String> data){
   aa.setData(data);
}

For more information on loaders, checkout this documentation. Note that if you're targeting an API less than 3.0 you'll need to use the Android Support Package.

Upvotes: 2

Related Questions