I had promised we'd look at finishing off the settings page this time around, but I've been busily beavering away on our app and thought it would be better to look at some of the core functionality instead. Don't worry, we'll come back to the settings page soon, but for now let's start adding the some real functionality to our Gizmodo UK app...

 

Parsing XML / RSS

As we discussed last time, Android apps are mostly written in Java -- there are more basic alternatives, but if you want to create something that works efficiently and on the widest range of handsets, there is no better option than getting your hands dirty with real Java code.

The Java implementation in Android isn't necessarily the same as it might be on other platforms -- in fact, Android doesn't contain a few core libraries; the intention being to improve performance and overhead when running Java code. For the most part, this isn't a problem but it does give us a hurdle to tackle as most of the existing Java RSS parsing implementations make use of these missing libraries.

One of the great things about modern programming languages is they promote code reuse -- and object oriented development and design makes this even more logical. Code makes use of 'classes' made up of 'methods'; to demonstrate with a simple (and overused metaphor), think of the code as a car; the wheels, engine, doors and chassis might be classes and the methods would be the components that make up these classes.

To build your car, you'd basically create instances of each of the classes and stick them together. You might have different types of class -- for example the base class might cover the front doors and then you may need to extend the class to create the back doors with slightly different elements but sharing the same basic properties -- a lock, a window, a latch.

With that in mind, our equivalent of a car would be the RSS code -- we'll split it into four logical classes; RSSLoader, RSSItem, RSSHandler and RSSListener.

We'll cover the RSSItem and RSSHandler code this week. All of the code for the working app will be available to download at the end of the project.

 

RSS Item

Starting with the simplest class, RSSItem, is simply a series of methods which take a piece of content and allow us to get and set the elements we're interested in. For now, those can be just the content link and the content title.

Let's first create the simple class structure. In the package explorer, browse to src > com.gizmodouk, right click and choose New File. Enter the filename RSSItem.java -- the skeleton code is really simple:

package com.gizmodouk;
public class RSSItem {
// item title
private String title;
// item link
private String link;
}

This defines a basic class which has two PRIVATE variables. Private variables are only visible within the class itself and can't be seen by any other class. We should try and keep variables private and only expose them via 'get' functions to ensure security and efficiency. So, we need to create the code that 'gets' and 'sets' these variables.

package com.gizmodouk;
public class RSSItem {
// item title
private String title;
// item link
private String link;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
@Override
public String toString() {
return title;
}
}

 

RSSHandler

This is where things start to get tricky. RSSHandler's main function is to parse (or walk) through the RSS feed, identifying elements and popping them into an ARRAY of RSSItems as we've defined them above. We take the basic RSS feed and step through each item looking for the title and link -- we're ignoring the other content elements for now, but if you want to include them in your app the concepts are similar.

Create a new file called RSSHandler,java the same way as you did above. This time around we'll be using a series of Java libraries, so the first thing to do is import them:

package com.gizmodouk;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.gizmodouk.RSSItem;

You'll notice that the last library we import is our own RSSItem class as defined above. This is because we'll be using this class to store things in as we walk through the feed. To do this we'll look for the start tags and end tags for the title and link, and once we find them we'll parse them and include them in our content array. The code below may look complex, but read it through and it'll make sense. We're extending the 'DefaultHandler' class that is part of the SAX library -- this means we're taking the basic class and adding further functionality to it.

public class RSSHandler extends DefaultHandler {
// List of items parsed
private List rssItems;
// We have a local reference to an object which is constructed while parser is working on an item tag
// Used to reference item while parsing
private RSSItem currentItem;
// We have two indicators which are used to differentiate whether a tag title or link is being processed by the parser
// Parsing title indicator
private boolean parsingTitle;
// Parsing link indicator
private boolean parsingLink;
public RSSHandler() {
rssItems = new ArrayList();
}
// We have an access method which returns a list of items that are read from the RSS feed. This method will be called when parsing is done.
public List getItems() {
return rssItems;
}
// The StartElement method creates an empty RssItem object when an item start tag is being processed. When a title or link tag are being processed appropriate indicators are set to true.
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if ("item".equals(qName)) {
currentItem = new RSSItem();
} else if ("title".equals(qName)) {
parsingTitle = true;
} else if ("link".equals(qName)) {
parsingLink = true;
}
}
// The EndElement method adds the current RssItem to the list when a closing item tag is processed. It sets appropriate indicators to false - when title and link closing tags are processed
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("item".equals(qName)) {
rssItems.add(currentItem);
currentItem = null;
} else if ("title".equals(qName)) {
parsingTitle = false;
} else if ("link".equals(qName)) {
parsingLink = false;
}
}
// Characters method fills current RssItem object with data when title and link tag content is being processed
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (parsingTitle) {
if (currentItem != null)
currentItem.setTitle(new String(ch, start, length));
} else if (parsingLink) {
if (currentItem != null) {
currentItem.setLink(new String(ch, start, length));
parsingLink = false;
}
}
}
}

 

Next Time...

We'll look at the two major remaining RSS classes and then we'll be ready to start putting everything together into a fully working app. Don't forget, at the end of the series we'll be making our app available to download for you all to have a go at modifying yourselves, so why not start thinking about what you would like from the app, and how you might go about achieving that?

Colin Polonowski is a developer at Giz UK’s parent company Future Publishing, working across a number of their sites. He also runs The Digital Fix in his spare time. Check in on the 18th of April for his next App Millionaire guide.

To get on-the-spot news, app tips and the full lowdown on Samsung’s latest mobile announcements check out Samsung’s Your Mobile Life over here.