Codename One is a set of tools for mobile application development that derive a great deal of its architecture from Java.

Codename One’s mission statement is:

Unify the complex and fragmented task of mobile device programming into a single set of tools, APIs & services. As a result create a more manageable approach to mobile application development without sacrificing the power/control given to developers.

This effectively means bringing that old "Write Once Run Anywhere" (WORA) Java mantra to mobile devices without "dumbing it down" to the lowest common denominator.

How Does Codename One Work?

Codename One unifies several technologies and concepts into a single facade:

  • API - abstracts the differences between the various devices.

  • Plugin - the only piece of software installed on client machines, it includes the following features:

    • IDE integration - preferences, completion, the ability to send a native build

    • Simulator - native device simulator that runs locally and allows debugging the application

    • Designer/GUI Builder - high level tools

  • Build Servers - The build servers accept native device builds sent by the plugin and convert the binaries (JAR’s, not sources) to native applications as explained below.

  • Cloud Servers - The cloud servers provide features such as push notification, cloud logging etc.

The Codename One tool-chain
Figure 1. The Codename One tool-chain

Why Build Servers?

The build servers allow building native iOS Apps without a Mac and native Windows apps without a Windows machine. They remove the need to install/update complex toolchains and simplify the process of building a native app to a right click.

E.g.: Since building native iOS applications requires a Mac OS X machine with a recent version of xcode Codename One maintains such machines in the cloud. When developers send an iOS build such a Mac will be used to generate C source code using ParparVM and it will then compile the C source code using xcode & sign the resulting binary using xcode. You can install the binary to your device or build a distribution binary for the appstore. Since C code is generated it also means that your app will be "future proof" in a case of changes from Apple. You can also inject Objective-C native code into the app while keeping it 100% portable thanks to the "native interfaces" capability of Codename One.

Subscribers can receive the C source code back using the include sources feature of Codename One and use those sources for benchmarking, debugging on devices etc.

The same is true for most other platforms. For the Android, J2ME & Blackberry the standard Java code is executed as is.

Java 8 syntax is supported thru retrolambda installed on the Codename One servers. This is used to convert bytecode seamlessly down to Java 5 syntax levels. Java 5 syntax is translated to the JDK 1.3 cldc subset on J2ME/Blackberry to provide those language capabilities and API’s across all devices. This is done using a server based bytecode processor based on retroweaver and a great deal of custom code. Notice that this architecture is transparent to developers as the build servers abstract most of the painful differences between devices.

Why ParparVM

On iOS, Codename One uses ParparVM which translates Java bytecode to C code and boasts a non-blocking GC as well as 64 bit/bitcode support. This VM is fully open source in the Codename One git repository. In the past Codename One used XMLVM to generate native code in a very similar way but the XMLVM solution was too generic for the needs of Codename One. ParparVM boasts a unique architecture of translating code to C (similarly to XMLVM), because of that Codename One is the only solution of its kind that can guarantee future iOS compatibility since the officially supported iOS toolchain is always used instead of undocumented behaviors.

XMLVM could guarantee that in theory but it is no longer maintained.

The key advantages of ParparVM over other approaches are:

  • Truly native - since code is translated to C rather than directly to ARM or LLVM code the app is "more native". It uses the official tools and approaches from Apple and can benefit from their advancements e.g. latest bitcode or profiling capabilities.

  • Smaller class library - ParparVM includes a very small segment of the full JavaAPI’s resulting in final binaries that are smaller than the alternatives by orders of magnitude. This maps directly to performance and memory overhead.

  • Simple & extensible - to work with ParparVM you need a basic understanding of C. This is crucial for the fast moving world of mobile development, as Apple changes things left and right we need a more agile VM.

Windows Phone
The Windows Phone/Mobile port is currently undergoing a complete rewrite.

On Windows Phone, XMLVM still used to translate the Java bytecode to C# at this time. Notice that the XMLVM backend that translates to C# is very different from the one that was used in the past to translates code for iOS.

JavaScript Port

The JavaScript port of Codename One is based on the amazing work of the TeaVM project. The team behind TeaVM effectively built a JVM that translates Java bytecode into JavaScript source code while maintaining threading semantics using a very imaginative approach.

The JavaScript port allows unmodified Codename One applications to run within a desktop or mobile browser. The port itself is based on the HTML5 Canvas API to provide a pixel perfect implementation of the Codename One API’s.

The JavaScript port is only available for Enterprise grade subscribers of Codename One.
Desktop, Android, RIM & J2ME

The other ports of Codename One use the VM’s available on the host machines/environments to execute the runtime. Retrolambda is used to provide Java 8 language features in a portable way, for older devices retroweaver is used to bring Java 5 features.

The Android port uses the native Android tools including the gradle build environment in the latest versions.

The desktop port creates a standard JavaSE application which is packaged with the JRE and an installer.

The Desktop port is only available to pro grade subscribers of Codename One.
Lightweight Components

What makes Codename One stand out is the approach it takes to UI where it uses a "lightweight architecture" thus allowing the UI to work seamlessly across all platforms. As a result most of the UI is developed in Java and is thus remarkably portable and debuggable. The lightweight architecture still includes the ability to embed "heavyweight" widgets into place among the "lightweights".

Lightweight Architecture Origin

Lightweight components date back to Smalltalk frameworks, this notion was popularized in the Java world by Swing. Swing was the main source of inspiration to Codename One’s predecessor LWUIT. Many frameworks took this approach over the years including JavaFX & most recently Ionic in the JavaScript world.

A Lightweight component is a component that is written entirely in Java, it draws its own interface and handles its own events/states. This has huge portability advantages since the same code executes on all platforms, but it carries many additional advantages.

Lightweight components are infinitely customizable by using standard inheritance and overriding paint/event handling. Since a lightweight component is written entirely in Java, developers can preview the application accurately in the simulators & GUI builder. This avoids many common pitfalls of other WORA solutions where platform specific behavior foiled any saved effort. Hence all the effort saved in coding was lost in debugging esoteric device only oddities.

Codename One achieves fast performance by drawing using the native gaming API’s of most platforms e.g. OpenGL ES on iOS.

Versions In Codename One

One of the confusing things about Codename One is the versions. Since Codename One is a SaaS product versioning isn’t as simple as a 2.x or 3.x moniker. However, to conform to this convention Codename One does make versioned releases which contribute to the general confusion.

When a version of Codename One is released the version number refers to the libraries at the time of the release. These libraries are then frozen and are made available to developers who use the Versioned Builds feature. The plugin, which includes the designer as well as all development that is unrelated to versioned builds continues with its regular updates immediately after release. The same is true for the build servers that move directly to their standard update cycle.

History

LWUIT App Screenshot
Figure 2. LWUIT App Screenshot circa 2007

Codename One was started by Chen Fishbein & Shai Almog who authored the Open Source LWUIT project at Sun Microsystems starting at 2007. The LWUIT project aimed at solving the fragmentation within J2ME/Blackberry devices by creating a higher standard of user interface than the common baseline at the time. LWUIT received critical acclaim and traction within multiple industries but was limited by the declining feature phone market. It was forked by several companies including Nokia, it was used as the base standard for DTV in Brazil. Another fork has brought a LWUIT fork into high end cars from Toyota and other companies. This fork later adapted Codename One as well.

In 2012 Shai & Chen formed Codename One as they left Oracle. The project has taken many of the basic concepts developed within the LWUIT project and adapted them to the smartphone world which is still experiencing similar issues to the device fragmentation of the old J2ME phones.

Installation

Installing Codename One In NetBeans

For the purpose of this document we will focus mostly on the NetBeans IDE for development, however most operations are almost identical in the Eclipse IDE as well. Eclipse installation instructions are in the next section.

These instructions assume you have downloaded a recent version of NetBeans (at this time 8.x), installed and launched it.

  • Select the Tools→Plugins menu option

Tools->Plugin menu option
Figure 3. Tools→Plugin menu option
  • Select the Available Plugins Tab

  • Check The CodenameOne Plugin

Netbeans Plugin Install Wizard
Figure 4. Netbeans Plugin Install Wizard
  • click the install button below. Follow the Wizard instructions to install the plugin

Netbeans Plugin Install Wizard step 2
Figure 5. Netbeans Plugin Install Wizard step 2

Installing Codename One In Eclipse

Startup Eclipse and click Help→`Install New Software`. You should get this dialog

Eclipse Install New Software
Figure 6. Eclipse Install New Software

Click the Add button on the right side & fill out the entries

Eclipse Add Repository Dialog
Figure 7. Eclipse Add Repository Dialog

Enter Codename One for the name and https://codenameone.com/files/eclipse/site.xml for the location.

Select the entries & follow the wizard to install

Eclipse Install Wizard select entries
Figure 8. Eclipse Install Wizard select entries

Installing Codename One In IntelliJ IDEA

Download & install IntelliJ/IDEA, notice that Android Studio will not work.

Install the plugin using The Plugin Center

Use the search functionality in the plugin center to find and install the Codename One plugin.

Hello World Application

This hello world application uses NetBeans but it should work just as well for Eclipse/IntelliJ.

Start by selecting the new project button (or menu item) in the IDE and selecting the Codename One project option.

New Project
Figure 9. New Project
New Project Dialog
Figure 10. New Project Dialog
New Project Dialog Step 2 - Select the project name/location
Figure 11. New Project Dialog Step 2 - Select the project name/location
Use a proper package name for the project!
Setting a proper package name
Figure 12. Setting a proper package name

By default a nice looking hello world project is created. We will maintain this default for the purpose of this walk-thru.

Default project structure
Figure 13. Default project structure

There are two important files that are generated:

  • SuperDuperApp.java - your main java source file, this is where your app starts/stops and handles system notifications (e.g push).

  • theme.res - the theme file contains the application styling, localization, images etc.

When we double click the theme.res file it opens in the Codename One designer tool. We can then edit the styles of any element within the theme. We will discuss theming in depth in the basics section and dig deeper later on.

The default theme created in the hello world wizard
Figure 14. The default theme created in the hello world wizard

To run the application just press the IDE’s play button and you should see something similar to The default hello world Codename One app

The default hello world Codename One app
Figure 15. The default hello world Codename One app

The Source Code Of The Hello World App

The hello world wizard generates a bit of code we’ll deconstruct it into smaller pieces to understand the inner workings of Codename One.

package com.acme.superduperapp;

import com.codename1.io.Log;
import com.codename1.ui.Button;
import com.codename1.ui.Display;
import com.codename1.ui.FontImage;
import com.codename1.ui.Form;
import com.codename1.ui.Label;
import com.codename1.ui.animations.CommonTransitions;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.layouts.FlowLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.ui.util.UITimer;
import java.io.IOException;

public class SuperDuperApp {
    private Form current;
    private Resources theme;

    public void init(Object context) {
        theme = UIManager.initFirstTheme("/theme");

        // Pro only feature, uncomment if you have a pro subscription
        // Log.bindCrashProtection(true);
    }

    public void start() {
        if(current != null){
            current.show();
            return;
        }
        Form hi = new Form("Welcome", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));
        final Label apple = new Label(theme.getImage("apple-icon.png"));
        final Label android = new Label(theme.getImage("android-icon.png"));
        final Label windows = new Label(theme.getImage("windows-icon.png"));
        Button getStarted = new Button("Let's Get Started!");
        FontImage.setMaterialIcon(getStarted, FontImage.MATERIAL_LINK);
        getStarted.setUIID("GetStarted");
        hi.addComponent(BorderLayout.CENTER,
                LayeredLayout.encloseIn(
                        BoxLayout.encloseY(
                                new Label(theme.getImage("duke-no-logos.png")),
                                getStarted
                        ),
                        FlowLayout.encloseRightMiddle(apple)
                    )
        );

        getStarted.addActionListener((e) -> {
            Display.getInstance().execute("https://www.codenameone.com/developers.html");
        });

        new UITimer(() -> {
            if(apple.getParent() != null) {
                apple.getParent().replace(apple, android, CommonTransitions.createFade(500));
            } else {
                if(android.getParent() != null) {
                    android.getParent().replace(android, windows, CommonTransitions.createFade(500));
                } else {
                    windows.getParent().replace(windows, apple, CommonTransitions.createFade(500));
                }
            }
        }).schedule(2200, true, hi);
        hi.show();
    }

    public void stop() {
        current = Display.getInstance().getCurrent();
    }

    public void destroy() {
    }
}

The class package and import statements should be self explanatory so we’ll focus on the class itself:

public class SuperDuperApp {
    private Form current;
    private Resources theme;

    public void init(Object context) {
    }

    public void start() {
    }

    public void stop() {
    }

    public void destroy() {
    }
}

The main class doesn’t implement any interface or extend a base class, however the Codename One runtime expects it to have these 4 methods and maintain the method signatures.

A common mistake developers make is writing code that throws a checked exception and then letting the IDE "auto-correct" the code by adding a throws clause to the parent method. This will fail during a device build.

We also keep two variables by default in a hello world application:

  • theme - allows us to set the look of the application. A theme object maps to the theme.res file where a lot of data can be stored e.g. images, localization etc.

  • current - the current application Form. A Form is the top level class responsible for placing a UI in Codename One. Think of it as you would think about a Frame in AWT, JFrame in Swing, Activity + View in Android, UIController + View in iOS & the html tag in HTML.
    This variable is used for the Suspend/Resume Behavior of the application.

The 4 builtin methods of the Codename One main class include:

  • init(Object) - invoked when the application is started but not when its restored from the background. E.g. if the app isn’t running, init will be invoked. However, if the app was minimized and is then restored init will not be invoked.
    This is a good place to put generic initializations of variables and the likes. We specifically use it to initialize the theme which is something we normally need to do only once per application execution.
    The object passed to init is the native OS context object, it can be null but can be ignored for 99% of the use cases.

  • start() - the start method is invoked with every launch of the app. This includes restoring a minimized application. This is very useful for initializing UI’s which usually need to be refreshed both when the user launches the app and when he returns to it after leaving it in the background for any duration.

  • stop() - stop is invoked when the user minimizes the app. If you have ongoing operations (e.g. download/media) you should stop them here or the operating system might kill your application due to CPU usage in the background.

  • destroy() - this callback isn’t guaranteed since an OS might kill the app and neglect to invoke this method. However, most OS’s will invoke this method before completely closing the app. Since stop() will be invoked first its far better to write code there.

By default Codename One applications save/restore the current form with code like this:

public void start() {
    if(current != null){
        current.show();
        return;
    }
    // rest of start method....
}

public void stop() {
    current = Display.getInstance().getCurrent();
}

Now all that remains is the content of the start() method, we’ll break the body into a few pieces for clarity:

Form hi = new Form("Welcome", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));

In this block we create a new Form named hi. We give it the title "Welcome" which will be displayed at the top. We also define the layout manager of the form to BorderLayout which allows us to place a component in one of 5 positions. In this case the BorderLayout allows us to place the component in the center of the screen. Normally a BorderLayout stretches the center component to take up the whole screen but we want Duke to be completely centered so we ask the layout to use the CENTER_BEHAVIOR_CENTER_ABSOLUTE behavior.

You can learn more about positioning components with layouts in the basics section.

final Label apple = new Label(theme.getImage("apple-icon.png"));
final Label android = new Label(theme.getImage("android-icon.png"));
final Label windows = new Label(theme.getImage("windows-icon.png"));

We create the images for the logos that fade in Dukes hand. We use the Label class to display the images. Notice that we get the images themselves from the theme resource file.

Multi Images

We could load a PNG directly from file but using the resource file carries an advantage as we can use multi images. Multi-images are a set of images adapted to device density [1].
A high resolution image is used during development and the Codename One designer adapts it to the various DPI’s. This simplifies the process of dealing with multiple device densities.

You can learn more about multi-images in the advanced theming section.

Button getStarted = new Button("Let's Get Started!");
FontImage.setMaterialIcon(getStarted, FontImage.MATERIAL_LINK);

The getStarted Button is pretty self explanatory however the next line installing the font image isn’t as clear.
FontImage allows us to take a font (TTF) and use it as an icon or an image. This is quite powerful as fonts are rendered smoothly in every device density & can easily be adapted to theme conventions/colors.

Codename One has the material design icon font built into it, this provides a good set of basic icons that all applications can reuse across all platforms. You can also pick a custom icon font and make use of that using one of the many resources available on the web.

The FontImage class allows us to create an Image object but in this case we chose to use setMaterialIcon. The benefit of using that approach is simple, this method automatically uses the buttons styling (color, font size etc.) for the icon image.

getStarted.setUIID("GetStarted");

The setUIID method allows us to define the theme styling used for a given component. By default a button would use the "Button" UIID so by changing this the button will have a different look.

To understand what that would look like just double click the theme.res file and select the theme. Then double click the "GetStarted" entry in the list, you should see something like this:

The GetStarted UIID in the theme file
Figure 16. The GetStarted UIID in the theme file

We will discuss theming further in the basics section.

hi.addComponent(BorderLayout.CENTER,
    LayeredLayout.encloseIn(
        BoxLayout.encloseY(
            new Label(theme.getImage("duke-no-logos.png")),
                getStarted
            ),
        FlowLayout.encloseRightMiddle(apple)
    )
);

The code above is a bit terse, it uses the shortened syntax for Codename One, if you are used to other frameworks a slightly more verbose version of the same code might be clearer:

Container tmpBoxLayout = new Container(new BoxLayout(BoxLayout.Y_AXIS));
tmpBoxLayout.add(new Label(theme.getImage("duke-no-logos.png")));
tmpBoxLayout.add(getStarted);
Container tmpFlowLayout = new Container(new FlowLayout(Component.LEFT, Component.CENTER));
tmpFlowLayout.add(apple);
Container tmpLayeredContainer = new Container(new LayeredLayout());
tmpLayeredContainer.add(tmpBoxLayout);
tmpBoxLayout.add(tmpFlowLayout);
hi.addComponent(BorderLayout.CENTER,tmpLayeredContainer);

What we are doing here is creating a ComponentContainer hierarchy that can be used to render them onto the screen. You can read more about the ComponentContainer hierarchy in the basics section.

The root Container is the hi Form onto which we add a Container with a LayeredLayout. This means that the elements placed directly into that LayeredLayout will be positioned one on top of the other, we need that so the logos for the supported platforms will appear in Dukes hand.

Then we place two containers, the first is a BoxLayout container on the Y axis. This means the elements within this layout will order themselves vertically in a column. We place the image for Duke within this layout followed by the button.

Next within the LayeredLayout we have a FlowLayout that is positioned to the right horizontally and to the middle of the available space vertically. This allows us to place the logos in Dukes hand which is roughly in that position. Initially we place the Apple logo within that layout and below we’ll cover the code that animates that logo.

You can gain insight into the Codename One component hierarchy by running the simulator and selecting the Simulate→Component Inspector menu option. This will present the component hierarchy as a navigatable tree.
hello world getting started hierarchy
Figure 17. Component hierarchy for the getting started hello world app
getStarted.addActionListener((e) -> {
    Display.getInstance().execute("https://www.codenameone.com/developers.html");
});

We can use event callbacks to perform actions within a Codename One application. In this case we are launching the browser to the Codename One website.

This code snippet uses Java 8 lambda syntax for simplicity. It is functionally equivalent to this listing.
getStarted.addActionListener(new ActionListenr() {
    public void actionPerformed(ActionEvent e) {
        Display.getInstance().execute("https://www.codenameone.com/developers.html");
    }
});

You can learn more about event handling in Codename One in the events section.

new UITimer(() -> {
    //...
}).schedule(2200, true, hi);
hi.show();

We’ll come back to the body of the UITimer soon. But first lets discuss the general concept…​

The UITimer class allows us to receive a callback within a fixed period of time. Here we schedule the timer to repeat (the true argument) every 2200 milliseconds. We need to bind this timer to the parent form, when we navigate to a different form it will no longer be active.

Java contains a Timer class within the java.util package. However it’s invoke within a separate thread which can cause issues when dealing with UI. The UITimer class can be used to handle UI in a seamless way.

As the final line of code in this demo we just show the form which should be self explanatory.

if(apple.getParent() != null) {
    apple.getParent().replace(apple, android, CommonTransitions.createFade(500));
} else {
    if(android.getParent() != null) {
        android.getParent().replace(android, windows, CommonTransitions.createFade(500));
    } else {
        windows.getParent().replace(windows, apple, CommonTransitions.createFade(500));
    }
}

The UITimer callback just replaces one component with another and uses the fade transition for the replace operation.

It checks the current state by checking if the parent component is null. E.g. when we replace the apple label with the android label the parent container for apple will become null.

Building & Deploying On Devices

Codename One project preferences
Figure 18. Codename One project preferences

You can use the project settings to configure almost anything. Specifically, the application title, application version, application icon etc. are all found in the project properties in the right click menu of your IDE.

Certificates

The most crucial thing for a final app is the developer certificate. The certificate indicates who the author of the app is and without it you won’t be able to ship your app or update your app.

Backup your Android certificate and save its password! We can’t stress this enough!
If you lose your Android certificate you will not be able to update your app.

To create an Android or iOS certificate just use the generate button within the respective section in the preferences.

To generate an iOS certificate you will need an Apple developer account which needs to be purchased from Apple and has a waiting period for approval (less than a week).

Certificates and provisioning are a big & complex subject that we cover in depth in the signing section.

You can reuse both Android and iOS certificates for all your applications. However, for iOS you will need to create provisioning profiles for every application.
Sending A Build

In order to get a native application for the devices you need to send a build to the build server. For that purpose you will need to signup at https://www.codenameone.com/ and click on the email validation link.

Once you signed up you can right click the project and select one of the build target options and a build will be sent to the servers.

Desktop & JavaScript builds are for high grade paying subscriptions. Free subscribers have a build quota limit imposed monthly and a jar size limit. This are in place to prevent excessive build server resource consumption.
Right click menu options for sending device builds
Figure 19. Right click menu options for sending device builds

Once the build is sent successfully you can get the result at https://www.codenameone.com/build-server.html

Build results on codenameone.com allow us to scan the QR code with our device to install instantly
Figure 20. Build results on codenameone.com allow us to scan the QR code with our device to install instantly
Older builds are cleared within 3 days from the build servers.

You can install the application either by scanning the QR code or emailing the install link to your account (using the e-mail Link button).

You can download the binaries in order to upload them to the appstores.

Application Lifecycle

Now that we have a basic understanding of Codename One it’s probably a good point to explain a core idea about the code above. Every Codename One application has a main class which serves as its "entry point". This class has the following 4 methods:

public void init(Object context) {}
public void start() {}
public void stop() {}
public void destroy() {}

These provide a set of simplified hooks into the application state in the operating system.

Android developers are used to Activity which provides a similar set of methods and far more functionality. However, since Activities are unique to Android their functionality cannot be reproduced in a portable way.

Applications are always launched with a call to init(Object), for historical reasons a native context object is passed but it’s often null and when it isn’t we don’t really need it anyway.

All Codename One callback methods are invoked on the event dispatch thread (EDT) which is the main thread of Codename One. Doing things like sleep loops or long running tasks within them is strictly prohibited.

init(Object) is a great place to initialize everything that needs to always be there. E.g. your application theme, crash protection etc.

start() is invoked immediately after init(Object) and every time an app is restored from background (more on that below).

stop() is invoked when the app is sent to background or minimized.

destroy() might be invoked when an app is killed by the OS. There is no guarantee that destroy will be invoked!

Suspend/Resume

Suspend happens when an app is minimized e.g. when a user presses the home button, when an incoming call takes over the phone etc.

These operations suspend the app and send it into suspended state. If the user chooses to return to a running app the app isn’t started from scratch, it’s resumed.

The behavior of the app during its suspended state is very OS specific but all OS’s place heavy restrictions on background operations. When an app is minimized its expected that it will quit all non-essential work (e.g. networking operations).

This means you should stop all of the "expensive" operations such as networking, GPS etc. when the stop() method is invoked and potentially restore them when start() is invoked.

You can simulate suspend/resume in the simulator menu, this won’t simulate the OS killing of your app but will allow you to debug the logic in the start()/stop() methods.


1 density indicates the amount of pixels for a given square inch of screen space e.g. an older iOS device would have 160ppi (pixels per inch) whereas iPhone 6+ has 540 ppi!