Tutorial

WORA On Devices - Introducing Codename One

Codename One co-founder Shai Almog explains the thinking behind the platform designed to make device development (iOS and Android included) easier for Java developers.

When I ran into Java for the first time, I was working with OS/2 and was busy with getting my GCC porting layers working for all platforms. Java was a revelation as it made working with all platforms trivial and painless. At first I bemoaned the lack of operator overloading, templates and various other features of C++. But as the years went by, I came to appreciate the simplicity of the language that allowed me to scale my work considerably on all platforms.

When Swing came out, it was a similar revelation in terms of GUI; suddenly all UI programming became portable and easy. Yes, you needed to work hard on the final refinement of the application, but you could get control of every pixel on the screen and get command amazing amount of power.

Six years ago, Chen Fishbein (best friend and partner at Codename One) started building a GUI library for mobile devices inspired by Swing. My initial knee jerk reaction was: don’t. Its too hard and Sun’s bureaucracy will never let something like this out of the door. I was right about it being hard but I was wrong about it being too hard. I was also wrong about Sun’s bureaucracy, which did indeed pose an issue, but our manager at the time (Yoav Barel) had the required tenacity to actually get this thing out of the door.

Fast forward to the present day, we took this effort (six years in the making) and made it even bigger. The Codename One open source project now encapsulates everything: from GUI Builder to IO and device APIs, cloud build servers and IDE integration. 

So what exactly is it? 

Think of it as how you would expect Java to work on devices, but adapted to the reality of current device architectures. Codename One is: 

  • An open source API and toolchain - this took years to perfect. We reimagined Swing for the device era with everything that we always wanted to have in Swing.
  • IDE integration for NetBeans/Eclipse.
  • Cloud build servers - since building for iOS requires a Mac and building for Windows Phone requires a PC with Windows 64 bit (no virtualization allowed), there is no technical way to build Java in the same way we did in 96. To make it “feel” the same we built a cloud that translates your bytecode to a native executable using Apple's/Google's & MS’s toolchain, creating native apps for every one of the platforms. 

So how does it work?

Lets start with a simple hello world:

public class MyApplication {
   private Form current;

   public void init(Object context) {
       try{
           Resources theme = Resources.openLayered("/theme");
           UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0]));
      }catch(IOException e){
           e.printStackTrace();
       }
   }
   
   public void start() {
       if(current != null){
           current.show();
           return;
       }
       Form hi = new Form("Hi World");
       hi.addComponent(new Label("Hi World"));
       hi.show();
   }

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

 

This is the hello world handcoded application that you will get after running the new application wizard. You should notice a few things about this application:

  • The application doesn’t have a main() method. It’s based on a “lifecycle” object more similar to an Applet since that is how phones/tablets work with “managed” application runtimes.
  • We show a Form which is the top level component similar to a Frame in Swing. Unlike Swing/AWT for example, we only have one form at a time, since that is pretty much how phones/tablets work.
  • We have a theme and a standardized resource file. The theme determines how the application looks across platforms.

Like Swing/AWT Codename One has a Container->Component hierarchy where elements are placed using a layout manager. This is immensely important for mobile devices where the DPI differs so radically between devices e.g. iPhone 3GS is 320x480 where the iPhone 4 is 640x960!

To build this application to run on a device, one only has to right click the project and send a build for the appropriate device family.

You will notice that I mentioned manual handcoded applications above. There are two basic Codename One applications: Handcoded & GUI Builder apps. The Codename One GUI builder relies on a resource file format to build a navigable UI visually which you can then map to code in the IDE.

Unlike standard Swing GUI builders which simply generate code we picked a radically different approach where the boilerplate code is generated to a base class and you as a developer just need to override methods within the generate class. This provides very clean separation between the generated sources and the user code preventing the problems of locked “magic” code blocks. This also allows developers to preview their GUI designer work very rapidly right within the GUI/Theme design tool.

In order to work on all devices Codename One had to make many compromises on the features it supports within the Java platform.For example, java.net is very complex and hard to support for all platforms. Instead Codename One offers the NetworkManager & ConnectionRequest classes that simplify network communications and hide many of the thread related complexities, which are a source of many device specific bugs.

This effectively means that taking an arbitrary JAR off the internet and linking it with a Codename One application probably won’t work as it might rely on features that are unavailable or unsupported by Codename One. To solve this Codename One introduced a library project type that also includes support for native device libraries (Android JARs, iOS's static libraries etc.). This code is taken directly from the Codename One kitchen sink demo:

Button send = new Button("Send Request");
       cnt.addComponent(send);
       send.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent evt) {
               InfiniteProgress ip = new InfiniteProgress();
               Dialog dlg = ip.showInifiniteBlocking();
               requestElement.setDisposeOnCompletion(dlg);
               requestElement.setUrl(url.getText());
               requestElement.removeAllArguments();
               requestElement.setPost(postOrGet.isSelected());
               if(responseType.isSelected()) {
                   requestElement.setContentType("application/json");
                   requestElement.addRequestHeader("Accept", "application/json");
               } else {
                   requestElement.setContentType("application/xml");
                   requestElement.addRequestHeader("Accept", "application/xml");
               }
               for(int iter = 0 ; iter < arguments.getComponentCount() ; iter++) {
                   Container currentArg = (Container)arguments.getComponentAt(iter);
                   String p = ((TextField)currentArg.getComponentAt(0)).getText();
                   String v = ((TextField)currentArg.getComponentAt(1)).getText();
                   requestElement.addArgument(p, v);
               }
               NetworkManager.getInstance().addToQueue(requestElement);
           }
       });

In the code above, you can see many of the staples of Codename One. We use an action listener to monitor a press of the button and once the button is pressed we show a progress indication dialog. The network request is sent using the NetworkManager by adding it to the request queue which dispatches it in order.

I hope this brief introduction gave you a short glimpse into the world of device development with Codename One. Being such a huge framework it is hard to distil the essence of Codename One into a single article. They say that all companies are now software companies, I believe they are all in the process of becoming mobile companies and when they do... I hope they use Java and Codename One.

Image courtesy of nrkbeta

Shai Almog
Shai Almog

What do you think?

JAX Magazine - 2014 - 03 Exclucively for iPad users JAX Magazine on Android

Comments

Latest opinions