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.

DojoX Mobile Android

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:

TweetView build profile
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 and dojo.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!

Download The Source

Download TweetView. The archive will work as soon as you unzip the file!