As promised in my previous blog post, in the following series of articles I will try to document the highs and lows of an android HTML5 application. Development is still ogoing, in fact the app is morphing from a simple RSS reader to something like a “web content explorer app”… the latest version includes the ability to pull a photostream from flicker. In this first part I will focus on :

Intel XDK new

HTML, CSS and jQuery

Intel XDK new

The whole app started as a playground where I could test out this platform, and I’m impressed. There isn’t much I can elaborate on here, not because the platform isnt great, but because it’s so easy to use. Everything is setup in a thoughtful and well laid out manner. I’ve never used cordova, weinre, or ripple before (all tolls that XDK uses), but it was such a breeze to start writing my app, emulate, test and build it. I especially like XDK’s test feature, which allows you to either launch your app by scanning a QR code, or simply selecting your app over WiFi, using the companion android app “intel xdk preview“. It makes testing on an actual device extremely easy. This is where the platform shines, in allowing the developer to focus on code, rather than the tools and infrastructure necessary to test and deploy and app.

HTML, CSS and jQuery

The app is entirely based on HTML, CSS and javascript. At this point in time I have not used any of the “bridge frameworks” which allow you to access some native platform features through javascript functions. That means even things like swiping are implemented in javascript. When I first started out, I implemented the swipe functionality using touchSwipe, a 3rd party jquery library that focuses on touchscreen events. I did however run into a problem with this library. The library binds to a DOM element of your choice. In my case this was the main “body” element so the user can swipe left or right anywhere on the screen to change the RSS feed they are seeing. However, on binding to the element, the library suppresses other events that happen within the element. So for example, tapping on a tile within the body element would not work, because the “click” event would not bubble up from the tile div… it would get consumed and stopped by the touchSwipe library. This wasn’t a problem on my older android devices (running android versions up to and including 4.3), however on the newest android kitkat 4.4 this was a problem.

So I pivoted and instead used jQuery mobile’s swiperight and swipeleft functions. They worked quite well, and I didn’t run into any event suppression problems. I am still experimenting with what constitutes a “right swipe” and “left swipe”. That is to say, one needs to carefully set thresholds of when the swipeleft or swiperight events are triggered. I found that the default settings were too sensitive, and when trying to scroll vertically, jquery mobile would fire a swipe event because I have a tendency of moving my finger in a slight arc when scrolling up or down (probably what most mobile users do). So I had to adjust the default threshold for the events like so:

The jquery mobile swipe event documentation page mentions the setting $.event.special.swipe.horizontalDistanceThreshold but I was unclear on how exactly to change it.

but I was unclear on how exactly to change it. The solution, as in many cases, was found in the fantastic stackexchange site, here. To re-iterate, you need to set the threshold before jquery mobile even loads (which is event before the document ready event fires), so as Gajotres mentions in his post, you’d need something like so: <script src="jquery.js"></script> <script> $(document).bind("mobileinit", function(){ $.event.special.swipe.horizontalDistanceThreshold (default: 30px); }); </script> <script src="jquery-mobile.js"></script>

As far as UI goes, it is based almost entirely on Sergey’s excellent Metro UI css. Again not much to say here, any developer with experience using the bootstrap framework will feel right at home, and thanks to Sergey’s work, everything pretty much works right out the box. I did however, want to experiment also with bootstrap directly, especially for the carousel I used in the photo slideshow (if you’re using the app, this is found via the menu > Show me photos > show slideshow). Here I ran into the obvious problem that the bootstrap css was conflicting with the metro UI css, leading to some unexpected UI features. My workaround was to enclose the carousel and it’s containing modal in a completely seperate html page, which only included the bootstrap css and javascript files, hence avoiding conflicts. There was one last hiccup here, since I naively just used a normal html link (the “a” element). But I still ran into problems because by default jQuery mobile binds to every “a” element and makes it an asynchronous call to the link, while keeping the results from the link within the original page. This is normally very helpful and accelerates single-page app development, but it wasn’t what I was after in this case since I actually wanted a completely new html page to avoid conflicts. In my case, the simple solution was to simply override jquery Mobile’s a binding with my own:

$('#showSlideshow').click(function(){ window.location = "./carousel.html"; });

(assuming the “a” element has an id of “showSlideshow” of course)

Last but not least, the perks of HTML5. I found the localstorage feature of HTML5 to be invaluable. The android app has no server side component (almost none – the marvelous YQL plays a fundamental part in this app – but more on that in a separate post) so all user preferences (like last feed viewed, and hopefully soon – offline viewing) are all stored on the mobile device itself, rather than a user profile that is retrieved from a server. Localstorage was perfect for this and i’ve used it for:

Simple key value storage to store what feed or category the user was last viewing, for example:

localStorage.setItem('category','photos');

Complex array storage via JSON.stringify and JSON.parse (since localstorage can only handle strings, not javascript objects). The app basically downloads content from various sources and stores them in a javascript array. For persistence and passing the arrays between one function and another (rather than using the global scope) the array is then stringified and placed into localStorage like so:

localStorage.setItem(‘titles’, JSON.stringify(titles));

When needed again, the array is recreated from local storage by parsing the contents like so:

var titles = JSON.parse(localStorage.getItem(‘titles’+feedName));

Simple, easy and convenient 🙂

I have to say, I am believing those people who say “I have seen the future… it’s in my browser”