Monday, July 2, 2012

ReignUPNP - An Android UPnP Digital Media Controller



As previously mentioned, we are working on a student research project to write a UPnP digital media controller. The application is focused on Android tablets. For those of you who have never heard of UPnP, Universal Plug and Play is a set of data protocols that allow interchanging data, especially with the focus on media.  It is similar to the concept of Apples AirPlay. An example of a system setup would be:

  • NAS - Network Attached Storage, makes stored media available via the network, grants access to meta data and media library via UPnP
  • XBMC - MediaCenter that supports UPnP, XBMC acts as a "media renderer" it displays the streamed media
  • ReignUPnP - Retrieve and navigate media library from NAS via UPnP. Control playback of media. Device discovery, which devices provide data and which are able to receive and render a stream? 

Unlike other Android applications we are using our own UPnP framework. Why that? 
Well we thought, you don't really get to know a technology like UPnP by using a framework which abstracts everything.  It turned out you get confronted with way more than you had expected. SSDP(Device Management), GENA (Eventing),  DIDL(Metadata) and SOAP are just a small subset. 

Although the application has all the features required by a UPnP controller the total size of the installed application is only 1.05 Megabyte.

So what would I do different if I would start all over again:
  • Use Scala instead of Java, although this would probably more than triple the size of the APK, the better maintainability would make up for it.
  • Use KXML from the beginning. Read my previous article why.

screenshot
Screenshot , navigating ReignUPNP


Sunday, March 4, 2012

Android XML Parsing/Serialization


Currently I'm working on a project for my university. The goal is to write a UPNP (Universal Plug and Play) control point for Android. Due to the nature of SOAP, which is used to interact with the different devices, we were confronted with a lot of XML parsing and serialization. To keep the code relatively clean and simple we decided to use "Simple", a Java framework for serialization and deserialization. All you have to do to generate XML with Simple is:

  • Annotate your Java classes.
  • Pass your object to a persister which generates the XML based on your annotations.

To parse XML you pass the XML to an instance of the persister and it will return an object.
Sounds simple and it is! So what is the downside? Halfway through the project we noticed that our browse requests were unbearable slow.  So I decided to figure out where the problem was. Using the android traceview tool it turned out that serialization of the request, as well as the parsing of the response took way to long.  After looking deeper into the generated trace log file the actual problem showed up,  reflections.

So what were the alternatives? 
Writing a SAX-based parser - Too much work to handle the current state, position in the XML.

A DOM-based parser - Another drawback of Simple was that due to a missing StAX implementation for Android it made use of DOM. In the beginning we were willing to accept the memory usage drawbacks that come with DOM, but if you get another chance why should you make the same mistake again?

A XML Pull Parser (XPP) - "Using XMLPullParser is an efficient and maintainable way to parse XML on Android." Jesse Wilson
This turned out to be our way of choice.  XMLPullParsers are better maintainable than SAX-Parsers and since you "build" your objects while you pull in the XML you are able to keep a lower memory footprint than with DOM.

Another bottleneck StringEscapeUtils XML unescape method
It seems the version of the StringEscapeUtils (3.1) we were using looks up every character of a String you pass in a HashMap (source reference). This was different in previous versions where the HashMap was only checked when an ampersand occurred.


Changing from Simple to KXML and to a custom unescape method speed up the BrowseRequest about 25 times (excluding the network delay).
But let the charts speak for themselves:



Table - Parsing of XML on Android (Time in seconds)










Chart - Comparsion of parsing process 









Process of serialization