This tutorial is for Dojo 1.6 and may be out of date.
Up to date tutorials are available.
TweetView: Android, Packaging, and Review
In the previous two posts, Getting Started with TweetView: Tweets and Mentions and TweetView: Creating the Settings View, we created the HTML, CSS, and JavaScript code required to power the TweetView mobile application. This tutorial will focus on implementing an Android theme, leveraging the Dojo build system to keep the application compact for production, and a basic review of the entire dojox.mobile-powered application.
Implementing the Android Theme
Throughout the course of creating the CSS that powers our application, we've hardcoded the iPhone theme into our app.html page. That allowed us to speed up development and worry about Android theming once the application was fully functional. The time for styling our application for Android is now!
The first task in theming our application for Android is implementing a small snippet of code that will detect the client's device type and show the proper Android or iPhone theme (instead of hardcoding the iphone.css file):
<script> (function(){ // Create a new LINK element, get reference to the HEAD tag which we'll inject it into var l = document.createElement("link"), h = document.getElementsByTagName("head")[0]; // Is this Android? var isAndroid = navigator.userAgent.indexOf("Android") > -1; // Add the appropriate stylesheet designations l.setAttribute("rel", "stylesheet"); l.setAttribute("href", "js/dojox/mobile/themes/" + (isAndroid ? "android/android.css" : "iphone/iphone.css")); // Inject into header h.insertBefore(l, h.firstChild); })(); </script>
To force your page into Android mode for debugging purposes, hardcode the Android theme just as we did the iPhone theme before.
Now your application will load the Android theme if the device is a mobile Android-based device; if it's not Android, the iphone theme is assumed. But what about Android-specific images for the application? No problem! First, we'll set parseOnLoad to false in our djConfig:
djConfig = { isDebug: true, baseUrl: './', modulePaths: { tweetview: 'js/tweetview' }, parseOnLoad: false };
Next we'll add a dojo.ready
block to change image paths in the widgets and then manually tell Dojo to parse the page.
// Use iOS images by default // Fix my image paths for android dojo.ready(function() { // If Android.... if(isAndroid) { var imagePath = "js/tweetview/resources/images/"; // Update image path on bottom tabbar dojo.forEach(document.getElementsByClassName("tweetviewRefresh"), function(btn) { dojo.attr(btn, "iconLoading", imagePath + "androidLoading.gif"); }); // Add a new "iconLoading" attribute to the TweetView instances dojo.attr(dojo.byId("tabBar"), "iconBase", imagePath + "iconStripAndroid.png"); } // Parse the page! dojox.mobile.parser.parse(); });
Note that we used document.getElementsByClassName and looped over it with dojo.forEach -- remember that for mobile builds, we're trying to avoid using dojo.query to save on our build size, which we'll note again below.
Great! Our simple application handles images for both Android and iOS devices.
Remove Cache-Preventing Meta Tags
Remember the the META tags we added to prevent caching during the development of widget?
<!-- prevent cache --> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="pragma" content="no-cache">
Remove those to allow the application to be cached on the device.
dojox.mobile and Builds
Creating a build for dojox.mobile applications is extremely important because we want our mobile applications to be a small as possible. Let's walk through the steps to create a compact build of our dojox.mobile application: TweetView.
dojox.mobile's Build Files
Typical build scripts are found within the Dojo Toolkit's util/build directory. dojox.mobile, however, features its own build scripts within the dojox/mobile/build directory. Within these "build.sh" and "build.bat" scripts, you'll see the following comment:
# Note:
# You may need to manually apply the following patch to your build script
# in order to completely remove all the unused modules from your build.
# The patch disables finding the dojo base modules being used from the
# dependent modules with a simple pattern matching, which sometimes
# unexpectedly picks up unused modules.
# For example, if you see query.js and NodeList.js baked into your build,
# while you are not using them, then it is worth trying the patch.
# The file to be patched is util/buildscripts/jslib/buildUtil.js.
#
# --- buildUtil.js-orig
# +++ buildUtil.js
# @@ -1506,7 +1506,7 @@
# var addedResources = {};
# - while((matches = buildUtil.baseMappingRegExp.exec(tempContents))){
# + while(false&&(matches = buildUtil.baseMappingRegExp.exec(tempContents))){
# var baseResource = buildUtil.baseMappings[matches[1]];
# //Make sure we do not add the dependency to its source resource.
Patch that file to create your custom Dojo build. Remember to change it back when you're done!
Read the comment above carefully. Remember how we used a custom method, _ViewMixin.getElements, instead of dojo.query? There's no need to add dojo.query as a dependency if all we need is getElementByClassName element collection. This will save our application in build size.
dojox.mobile Build Options
A special build syntax is also laid out within the build.sh and build.bat files:
#!/bin/sh if [ $# -eq 0 ]; then echo 'Usage: build separate|single [webkit]' echo ' separate Create mobile.js that includes only dojox.mobile' echo ' single Create a single dojo.js layer that includes dojox.mobile' echo ' webkit Enable webkitMobile=true option (Loses PC browser support)' exit 1 fi optimize=shrinksafe profile=mobile dir=release-mobile-separate webkit= if [ "$1" == "single" ]; then profile=mobile-all fi if [ "$1" == "single" ]; then dir=release-mobile-single fi if [ "$2" == "webkit" ]; then webkit=webkitMobile=true fi cd ../../../util/buildscripts ./build.sh profile=$profile action=release customDijitBase=true optimize=$optimize layerOptimize=$optimize cssOptimize=comments releaseDir=../../$dir/ $webkit cd ../../dojox/mobile/build
We'll choose to use the separate
designation. Unfortunately the build file has a few hardcoded values we don't want, so let's copy this and create a build-tweetview.sh
file:
optimize=shrinksafe profile=tweetview dir=tweetview-release webkit= if [ "$2" == "webkit" ]; then webkit=webkitMobile=true fi cd ../../../util/buildscripts ./build.sh profile=$profile action=release customDijitBase=true optimize=$optimize layerOptimize=$optimize cssOptimize=comments releaseDir=../../$dir/ $webkit cd ../../dojox/mobile/build
We've updated the profile
and dir
settings to be more tweetview-centric.
TweetView Build Profile
Let's create a build profile for TweetView, based on the mobile-all.profile
build file:
dependencies = { stripConsole: "normal", layers: [ { name: "dojo.js", customBase: true, dependencies: [ "dojo._base.declare", "dojo._base.lang", "dojo._base.array", "dojo._base.window", "dojo._base.event", "dojo._base.connect", "dojo._base.html", "dijit._WidgetBase", "dijit._base.manager", "dojox.mobile.parser", "dojox.mobile" ] }, { name: "../dojox/mobile/compat.js", dependencies: [ "dijit._base.sniff", "dojo._base.fx", "dojox.mobile.compat" ] }, { name: "../tweetview/tweetview-app.js", dependencies: [ "tweetview.TweetView", "tweetview.SettingsView", "dojox.mobile.TabBar" ] } ], prefixes: [ [ "dijit", "../dijit" ], [ "dojox", "../dojox" ], [ "tweetview", "../tweetview" ] ] };
The mobile
profile provided by the Dojo Toolkit includes the dojox.mobile.app
classes that we don't need for our simple TweetView application, so I have removed them. I've added a tweetview.js designation for the build, which includes TweetView
, SettingsView
, and dojox.mobile.TabBar
(a class which isn't included within dojox.mobile
by default). The tweetview
namespace is then added to the prefixes
array.
Running the Build
Let's switch to the command line and build our widget based on the build profile above:
./build.sh single webkit
After the build is completed, navigate to the js/tweetview-release/dojo/tweetview/ directory to view the result:
The resulting release folder and its contents pertaining to TweetView.
Implementing the Build
To implement our newly created build files, open app.html, update the path to Dojo, and create a new SCRIPT node to retrieve the minified TweetView application:
<script src="js/tweetview-release/dojo/dojo/dojo.js"></script> <script src="js/tweetview-release/dojo/tweetview/tweetview-app.js"></script>
We could use dojo.require
to pull in the tweetview application, but there are some mobile operating systems that do not allow synchronous XHR, which can break dojo.require
, and so it's more reliable to source in the file directly in this one very specific case. The requires within our application will be fine, since we're using a build and loading all of our requirements in one file.
TweetView Review
TweetView is complete! Our simple mobile application has been templated (HTML), styled (CSS), coded (JavaScript), and built for production! Let's review what we learned in the process of create TweetView:
- The basic widgets included within
dojox.mobile
- How to theme a
dojox.mobile
application to look like iOS and Android devices - The format which to declaratively code
dojox.mobile
widgets with HTML and programmatically create widgets with JavaScript - How to use
dojo.io.script
anddojo.DeferredList
to retrieve JSON-formatted data from Twitter - How to extend
dojox.mobile
base widgets - Strategies behind following good JavaScript practices but also keeping code compact and minimized in dependencies
- The special build process needed for
dojox.mobile
applications
I'm hoping you ended this project with the same feelings about dojox.mobile
that I have: dojox.mobile
is an outstanding mobile application framework complete with themes and widgets to match mobile device controls. dojox.mobile is also easy to learn, extend, and dynamically populate with content. TweetView, a basic three-view applications, was very easy to create, thanks to dojox.mobile
!
dojox.mobile Will Only Get Better!
dojox.mobile
is growing at a considerable rate due to the push by the Dojo team to provide the best mobile solution. Look forward to more widgets, more code-efficient and processing-efficient widget controls, and device-specific functionality. I encourage you to take the time to experiment with dojox.mobile
and share your experiences with the rest of the Dojo community!
Click here to see the completed application in action!