This documentation relates to previous versions of Titanium.

To see the latest documentation, visit docs.appcelerator.com.

Skip to end of metadata
Go to start of metadata
Chapters

Summary

This guide covers how to get started extending Titanium for Android. In this guide, you should learn the following:

  • Getting your Environment setup to build Android modules
  • Building an Android Module
  • Packaging an Android Module
  • Understanding the Android Module API

Titanium Android Module Developer Guide

In order to use the Android Module SDK, you must have knowledge of the Android SDK. This guide assumes you have a good understanding of building applications using the native Android SDK.

Requirements

  • Titanium Mobile SDK 1.5.0 or above
  • A recent version of Python (>= 2.5) on your PATH or configured with PYTHONHOME.
    • In Windows, Titanium Developer / Desktop ships with Python 2.5, so no extra configuration is needed.
  • Oracle JDK
  • Android SDK, in accordance with the Prerequisite Android SDK and Android SDK compatibility matrices
  • Ant 1.7.1 or above in your PATH
    • If you don't want to install Ant separately, you can optionally use Eclipse

Environment setup

Follow the instructions in the Titanium Command Line Interface Environment Setup section

Creating a module

To create a module, we need to pass some arguments to the titanium create command, namely:

  • The module's name ($MODULE_NAME) and ID ($MODULE_ID)
  • The platform we're creating a module for (android)
  • The top-level path to your installation of the Android SDK ($ANDROID_SDK) (e.g. /opt/android-sdk)

For an Android module, we can create it with the following command from the parent directory of where you want the module created:

As an example, we'll create a module that performs simple addition and subtraction, call it the "calc" module, and give it an ID of "org.appcelerator.calc". Here we use /path/to/android-sdk to point to the place where we extracted the Android SDK.

If this was successful, there should be a calc folder under the current directory.

Module project layout

Inside the module folder, you'll see a tree of files and directories that have been generated:

  • LICENSE - The module's full license text
  • build.properties - An Ant properties file that contains the location to the Titanium SDK and Android SDK
  • build.xml - The main Ant build script - You will use this to build, distribute, and test your module
  • manifest - The module's manifest that contains version, author, license, copyright, name, id, GUID, and platform information
  • timodule.xml - A place to put custom activities, and general XML for insertion in AndroidManifest.xml (more doc coming soon)
  • hooks - A directory with scripts that will be called when a module is added/installed/removed/uninstalled from a project (this is still a WIP)
  • documentation - A generated Markdown file lives here that contains example documentation for your module
  • assets - Module specific assets such as images live here (see the README)
  • lib - Place any third party JAR dependencies here and they will be automatically added to your project's classpath and module zip
  • src - The source code for your module(s)
  • example - The module example project

Eclipse integration

Titanium also creates the necessary files so that you can import your module project directly into Eclipse. In Eclipse, simply follow these steps:

  • In the top level menu, Click on *File* > *Import...*
  • Expand the *General* folder, and double click on *Existing Project into Workspace*
  • Click on *Browse...* next to the *Select root directory* text field
  • Choose your module project's folder
  • You should see your module project under the *Projects* list:

  • Press *Finish* and your module project should now be visible from the *Package Explorer* view in Eclipse

Building the module zip

The zip under the dist folder is the module's distributable form. It generally follows the naming pattern $MODULE_ID-android-$MODULE_VERSION.zip.

The zip contains:

  • The compiled JAR with classes, generated bindings, and resources from the module project (built from the src folder)
  • Third-party JARs found in the lib folder
  • The module manifest, which includes deployment metadata such as author, version, license, copyright, etc
  • The module's timodule.xml

Building from command line / Ant

If ant is already on your PATH, then simply execute it from the top level directory of your module.

On the first build, you should see output similar to this:

Building from Eclipse

If you don't have ant in your PATH, or prefer using Eclipse, just follow these steps to build your module from within Eclipse:

  • Right click on build.xml under your module project
  • Click *Run As* > *Ant Build* (the first option)
  • You should see output similar to above

Module Distribution

To use your module in a Titanium Mobile app, follow these steps:

  • Copy the module zip to the root of the Titanium app, or to the root of the system Titanium installation
  • In the application's tiapp.xml, add the following XML inside <ti:app>:
  • Use the require function to load the module in the app's code, Example:
  • The next time the app is Launched or built, the module should be included with the application

Testing with the embedded Example project

The easiest way to get started with your module is to start writing code in the example/app.js file, and use ant to run and test your module's code. The example folder is equivalent to the Resources folder of the application, so feel free to copy data files and other code there for testing purposes.

The process for running the example project is simply:

  • Run the android emulator once
  • Once the emulator is booted, you can run your example app and module as many times as you like

Running the Android emulator

From command line, run this inside your module project:

You should see the emulator output on your console

From Eclipse, setup a launch configuration:

  • Right click on build.xml, click on *Run As* > *Ant Build...* (the 2nd option)
  • A window will open with configuration settings for a new launch configuration
  • Under *Check targets to execute, uncheck the **dist* target, and check the *run.emulator* target
  • Rename the *Launch Configuration* to something memorable, such as run emulator
  • An example of what the window looks like with the calc module example:

  • Click *Apply, then **Run*
  • From now on you can run the *Launch Configuration* from *External Tools* menu in *Run*, or the toolbar entry

  • You should see the emulator output in the *Console* view of Eclipse

Running the Example project

Once the emulator is up and running, you just need to wait for the unlock screen to appear, and you can start running your project. Make sure to unlock the screen so you'll see the example project when it launches.

From command line, run this inside your module project:

From Eclipse, setup a launch configuration:

Follow the same steps from the Launch configuration setup above, but use the *run* target instead of the *run.emulator* target. You should also name the configuration something different, for example *run calc project*

Troubleshooting tip:

If the *run* target times out trying to find the emulator, you can restart the ADB server by issuing the following two commands:

At this point, if you've successfully run the module example project, you should see a default "hello world" app open in the emulator:

Generated Module and Example proxy

As part of the initial project creation, Titanium generates two classes that are used by the Example project:

  • The module class, for example: src/org/appcelerator/calc/CalcModule.java
  • An example proxy class, for example: src/org/appcelerator/calc/ExampleProxy.java

Review these to get a basic idea for how Modules and Proxies are exposed to Javascript, and move on to the next section for a brief overview of the Titanium and Kroll APIs

Android Titanium API

Modules and Proxies (Kroll part 1)

  • A module is a static and optionally top level API point that can always be accessed with the same name. Titanium.UI and Titanium.App are two examples of modules that live under the top level Titanium object.
  • A proxy is a dynamic object that can be created or queried by the user through a module or another proxy's API. When you create a native view with Titanium.UI.createView, the view object is itself a proxy.
  • Both modules and proxies can expose methods, properties, constants, and getters/setters to the Javascript API

Modules

Proxies

Exposing methods and properties (Kroll part 2)

Methods

Methods of a proxy or module are exposed with the @Kroll.method annotation. A simple example:

If the method you're exposing requires the current Activity, you can add a KrollInvocation object as the first argument:

Methods have many other options, see the @Kroll.method Javadoc for more

Properties

Properties can be exposed two different ways in Kroll:

  1. As a getter/setter method with @Kroll.getProperty, and @Kroll.setProperty annotations. Getter/setter methods can also be exposed as Kroll methods (this is the pattern we usually follow in Titanium)
  2. As an object field with the @Kroll.property annotation (this uses reflection, and therefore is a little slower)

This example exposes a getter and setter for the message property as well as exposing methods with the same name

In JS, this could be used like so:

Constants

A constant is simply a static property on a @Kroll.module. The field that is annotated with @Kroll.constant must be static and final. Here's an example:

Constant can now be referred to directly: Ti.My.CONSTANT == 100

Views

Views in Titanium must have two classes:

  • The view proxy: A subclass of TiViewProxy
    • Responsible for exposing methods and properties of the view to Javascript (just as a normal proxy would do).
    • Implements TiUIView createView(Activity activity) which returns a new instance of TiUIView
    • In many cases, you'll want to call your UIView from the UI thread. See @Kroll.method#runOnUiThread
  • The view implementation: A subclass of TiUIView
    • Must call setNativeView with an instance of View either in the constructor, or in processProperties
    • The view implementation is responsible for taking data from the view proxy, and applying it directly to the native View that it exposes
    • The class can optionally implement propertyChanged and processProperties to be notified when the user sets a property on the proxy

For a simple example, see the Button implementation in ButtonProxy and TiUIButton

Heavyweight and Lightweight Windows

When the user creates a window with the Titanium.UI.createWindow API, a few checks are performed to tell if the window should be "heavy weight" or not:

  • A window is heavyweight if it has any of these properties: fullscreen, navBarHidden, modal, windowSoftInputMode, or if the tabOpen property is true
  • Otherwise, the window is lightweight
  • Heavyweight windows create a new Activity on the stack, and always create a new Javascript Context for their window
  • Lightweight windows create a full screen view (in the same activity as the calling code). If the url property is set, then a new Javascript Context is also created for the window.

Thread safety

Since a method or property can be invoked from any Javascript Context (and potentially any Activity / Thread), it's important to keep in mind thread safety when designing your API.

To ensure that a method is executed on the UI thread, you can use @Kroll.method#runOnUiThread. Here's an example: