user1446632
user1446632

Reputation: 427

RSS in Android 4.0 and above - AsyncTask

I have been creating an app recently that I am working on. The app simply shows the contents of a RSS feed in a ListView where the list items is clickable. It worked on Android 3.0 and below, but once i upgraded my app and device to 4.0 and above, it failed. I can see that I need to use a custom thread because of the NetworkOnMainThreadException, so I have chosen AsyncTask. I simply have a listview in my XML with id android:id/list and the code I use to load the feed looks like this:

//Load RSS news feed
// Initializing instance variables
        headlines = new ArrayList();
        links = new ArrayList();

        try {
            URL url = new URL("http://www.vg.no/rss/create.php?categories=25,10,49,26,23,20,21,12,32,30,34&keywords=85,98,1724,84,476,821,820,512,8317,343&limit=15");

            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(false);
            XmlPullParser xpp = factory.newPullParser();

                // We will get the XML from an input stream
            xpp.setInput(getInputStream(url), "UTF_8");

                /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
                 * However, we should take in consideration that the rss feed name also is enclosed in a "<title>" tag.
                 * As we know, every feed begins with these lines: "<channel><title>Feed_Name</title>...."
                 * so we should skip the "<title>" tag which is a child of "<channel>" tag,
                 * and take in consideration only "<title>" tag which is a child of "<item>"
                 *
                 * In order to achieve this, we will make use of a boolean variable.
                 */
            boolean insideItem = false;

                // Returns the type of current event: START_TAG, END_TAG, etc..
            int eventType = xpp.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                if (eventType == XmlPullParser.START_TAG) {

                    if (xpp.getName().equalsIgnoreCase("item")) {
                        insideItem = true;
                    } else if (xpp.getName().equalsIgnoreCase("title")) {
                        if (insideItem)
                            headlines.add(xpp.nextText()); //extract the headline
                    } else if (xpp.getName().equalsIgnoreCase("link")) {
                        if (insideItem)
                            links.add(xpp.nextText()); //extract the link of article
                    }
                }else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
                    insideItem=false;
                }

                eventType = xpp.next(); //move to next element
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Binding data
        ArrayAdapter adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1, headlines);

        setListAdapter(adapter);
    } catch (RuntimeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        Toast.makeText(getApplicationContext(), "Cannot load news, please check internett connection", Toast.LENGTH_LONG).show();
    }

I have been trying to understand it; however, I cannot get it to work. If someone could please help me put all of this in AsyncTask and call the RSS refresh on onCreate() and on onClick() and explain how, it would be great.

Thanks!

Upvotes: 0

Views: 1025

Answers (1)

CQM
CQM

Reputation: 44228

this is a boilerplate inline AsyncTask method

new AsyncTask<Void, Void, Void>({

//initialize headlines here or outside of here or before this Asynctask
    headlines = new ArrayList();
    links = new ArrayList();

@Override
protected Void doInBackground(Void... params)

 try {
        URL url = new URL("http://www.vg.no/rss/create.php?categories=25,10,49,26,23,20,21,12,32,30,34&keywords=85,98,1724,84,476,821,820,512,8317,343&limit=15");

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(false);
        XmlPullParser xpp = factory.newPullParser();

            // We will get the XML from an input stream
        xpp.setInput(getInputStream(url), "UTF_8");

            /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
             * However, we should take in consideration that the rss feed name also is enclosed in a "<title>" tag.
             * As we know, every feed begins with these lines: "<channel><title>Feed_Name</title>...."
             * so we should skip the "<title>" tag which is a child of "<channel>" tag,
             * and take in consideration only "<title>" tag which is a child of "<item>"
             *
             * In order to achieve this, we will make use of a boolean variable.
             */
        boolean insideItem = false;

            // Returns the type of current event: START_TAG, END_TAG, etc..
        int eventType = xpp.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            if (eventType == XmlPullParser.START_TAG) {

                if (xpp.getName().equalsIgnoreCase("item")) {
                    insideItem = true;
                } else if (xpp.getName().equalsIgnoreCase("title")) {
                    if (insideItem)
                        headlines.add(xpp.nextText()); //extract the headline
                } else if (xpp.getName().equalsIgnoreCase("link")) {
                    if (insideItem)
                        links.add(xpp.nextText()); //extract the link of article
                }
            }else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
                insideItem=false;
            }

            eventType = xpp.next(); //move to next element
        }

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

@Override
protected Void onPostExecute() //UI THREAD STUFF , onPostExecute may need an argument, not sure yet though
    ArrayAdapter adapter = new ArrayAdapter(this,
            android.R.layout.simple_list_item_1, headlines);

    setListAdapter(adapter);
}

}).execute();

good luck, you can put a loading progress bar in onPreExecute()

Upvotes: 2

Related Questions