I'm working on an android application where I'll be using the SAX quite a lot. I was wondering what would be the best way to send 'data' or results from my handler back to my activity?
IMO it's kind of messy to call intents or create toasts etc within my handler, and I'd prefere to do those kind of things from my activity, depending on what happens within my handler.
What do you guys think? How should I do this in a clean way?
Here's a code example:
public void startElement(String n, String l, String q, Attributes a) throws SAXException{
if(l == "login") in_loginTag = true;
if(l == "error") {
if(Integer.parseInt(a.getValue("value")) == 1)
Toast.makeText(getApplicationContext(), "Couldn't connect to Database", Toast.LENGTH_SHORT).show();
if(Integer.parseInt(a.getValue("value")) == 2)
Toast.makeText(getApplicationContext(), "Error in Database: Table missing", Toast.LENGTH_SHORT).show();
if(Integer.parseInt(a.getValue("value")) == 3)
Toast.makeText(getApplicationContext(), "Invalid username and/or password", Toast.LENGTH_SHORT).show();
error_occured = true;
}
I'd prefere not showing these Toasts from my handler class.
I've done quite a bit of XML parsing in my current app and this is this example helped a lot .
Design wise i believe instead of toasts or intent broadcasting etc you should be using a custom SAX Handler which will instantiate a Parse object at the beginning XML element. This object is a representation of your XML items. So maybe the object will be Car and have a setter/getter for Door, Colour, Wheels. As your parsing the data in the SAX parser you will set those values. when the SAX parser finishes parsing you call your parser to have it pass back the object to your activity which is full with all cars from your XML. In my case i actually populate a list/array of my objects which are passed back. The example only deals with one set of data. Anyway that link explains it all.
Edit: Was just looking at my code, actually what I do in my handler is build an array of my ParsedData set objects which are passed back to the activity after parsing is complete via getParsedData(). Here is some of the important code:
XML handler:
private boolean in_IdSite;
private boolean in_SiteName;
private ArrayList<ParsedChannelDataSet> list = new ArrayList<ParsedChannelDataSet>();
public ArrayList<ParsedChannelDataSet> getParsedData() {
return this.list;
}
@Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
// first tag parsed so add a new ParsedEventDataSet object
if(localName.equals("stmSiteUser")) {
list.add(new ParsedChannelDataSet());
} else if (localName.equals("idSite")) {
this.in_IdSite = true;
} else if (localName.equals("siteName")) {
this.in_SiteName = true;
}
}
@Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
if (localName.equals("idSite")) {
this.in_IdSite = false;
} else if (localName.equals("siteName")) {
this.in_SiteName = false;
}
}
@Override
public void characters(char ch[], int start, int length) {
// determine if any tag is current, get data from tag and populate into ParsedEventDataSet
if (this.in_IdSite) {
this.list.get(this.list.size()-1).setExtractedIdSite(new String(ch, start, length));
} else if (this.in_SiteName) {
this.list.get(this.list.size()-1).setExtractedSiteName(new String(ch, start, length));
}
}
Here is my sample ParsedDataSampleSet (this can be called whatever you want) obviously you want to replace siteName and idSite with something else too. These are just my XML elements
public class ParsedChannelDataSet {
private String extractedIdSite = null;
private String extractedSiteName = null;
public String getExtractedIdSite() {
return extractedIdSite;
}
public void setExtractedIdSite(String _extractedIdSite) {
this.extractedIdSite = _extractedIdSite;
}
public String getExtractedSiteName() {
return extractedSiteName;
}
public void setExtractedSiteName(String _extractedSiteName) {
Log.d("", _extractedSiteName);
this.extractedSiteName = _extractedSiteName;
}
public String toString() {
/* TODO */
return "todo";
}
}
So you can see I build an array of ParsedChannelDataSet objects which are passed back to the activity. this is a far better solution than using toast or broadcasts because its a more decoupled solution
Edit 2: The first post on this 2nd page of the site I linked mentions about parsing multiple XML elements like mine. See here (parse multiple xml elements).
I hope this helps you out
You could:
Pass the activity into the XML
handler, store it as an instance
variable, and call back to it as
needed.
Create a static member in your activity and assign the activity to
it when it's created. Then from your XML handler, you could reference ActivityClass.getMyActivity() [for example] and call some method to pop toast.
iOS/Mac OS X has a concept called "notifications" where any code can register an interest in some event. If there's an Android equivalent, that'd be another way to do this, i. e. the XML handler could broadcast some sort of failure event/notification and the Activity could listen for it and pop toast.
I would use a custom Handler
which I created in my activity and passing it to the XML parser. Then within this parser I could call some sendMessage
on the custom Handler.
An example usage of Handler here.