Port Native Android App to iOS: Part I
Port Native Android App to iOS: Part I
In this quick tutorial, we will walk you through the paces of converting a simple Android application to a Codename One application.
Join the DZone community and get the full member experience.Join For Free
We get contacted quite a bit about the prospect of porting applications that were already written using the Android API. In this quick tutorial, we will walk you thru the paces of converting a simple Android application to a Codename One application. We will also start with some basic tips covering the differences between Android & Codename One development.
I chose this application because it is simple. Making the application "pretty" isn’t a goal of this tutorial although I tried to make the application look reasonably good while trying to stay loyal to the original design (if you are interested in "pretty" check out this post).
I’ve changed a few things in the final app e.g. removed the overflow, changed the icon etc. so the app doesn't look completely alien on the various app stores.
The full source code of the app is here: https://github.com/codenameone/SwiftnotesCN1
This series is divided into 3 parts:
- Introduction - we review Codename One and how it compares to Android
- First Steps- get something simple running
- Finished app and final thoughts
How Does Codename One Differ From Android Development?
Codename One allows Android developers familiar with Java to instantly build native applications for Android, iOS, Windows and other platforms.
Codename One has the following additional advantages besides portability:
- A fast simulator - Despite recent advances in the emulator. The build process and app connection are still frustratingly slow on Android
- Standard Java debugging and profiling tools
- Resources are automatically scaled to the different DPI’s in the tools
- No need to deal with manifests and permissions (Codename One automatically detects and applies the necessary permissions). Notice this is implicitly Marshmallow compatible as well, so permission prompts are implicitly shown.
- Codename One hides the differences between versions on Android
- Since Codename One doesn’t package GUI XML’s into the final product it is harder to reverse engineer a Codename One application
- Component hierarchy (views) is much simpler in Codename One
- Works with all major IDE’s (NetBeans, Eclipse & IntelliJ/IDEA)
- All inclusive by default - no need for mixing and matching multiple disparate tools
In Android developers build user interfaces in XML by nesting layout views and view elements one within another (you can write Android apps in code but that isn’t as common). These elements are translated by the compiler and in order to bind code to them you need to "find" them by their ID to use them. Codename One differs in several ways:
- You can build Codename One applications either via the GUI builder which uses a more traditional code generator approach or write Java source code manually.
Componentis Codename One’s equivalent of a view,
Component(think of it as a
- All layouts are applied to the Container class essentially decoupling layout from
E.g. Android’s linear layout is essentially very similar to the box layout in Codename One. So to arrange components in a row in Codename One we can do something like:
Container cnt = new Container(new BoxLayout(BoxLayout.X_AXIS)); cnt.add(button1); cnt.add(button2); cnt.add(button3);
This can also be written as shorthand like this:
Container cnt = BoxLayout.encloseX(button1, button2, button3);
You can do the same with the GUI builder as well using simple drag and drop.
To read more about the different types of layouts and how they can be nested/used you can follow the section on layout managers in the developer guide or check out the layouts section in the javadocs.
Fragments essentially solve an issue with Android which mixed
View in a hierarchy creating a somewhat complex scenario for dynamic architectures.
The concept is powerful, yet it isn’t portable, convenient or robust. Fragments become unnecessary because of the much simpler Codename One hierarchy. Since Codename One doesn’t have a real equivalent of
Activity the UI elements don’t need it either e.g.
Tabs work with
Multiple DPI’s & 9-Patch Borders
Codename One supports a multi-image format which is roughly identical to the multiple DPI directories commonly used in Android. Unlike Android the Codename One designer tool automatically scales the images to all the resolutions (using high quality scaling algorithm) saving you the need to maintain multiple resolution support.
The same is true with Codename One’s 9-part image borders. However, unlike Androids very elaborate 9-patch borders Codename One borders are far simpler.
Codename One uses tiling for border images (instead of scaling) and breaks the images down, it also includes an image cutting wizard and internally cuts the images to 9-pieces.
Android’s 9-patch images are VERY powerful but also very hard to implement on all platforms in a performant way. They are also a very difficult concept to grasp for most developers.
Codename One has its own lifecycle object which acts a bit more like an application than the activity does, it’s somewhat simpler to program to.
Codename One supports firing intents although that is mostly Android specific and won’t work on other platforms.
You can execute arbitrary URL’s to launch external applications when necessary. Notice that iOS, Windows etc. don’t have anything remotely close to activities.
Codename One has two different classes that match the activity.
Form is the top-level component that you can "show" & transition. The main class for Codename One itself gets lifecycle events similar to the
Activity lifecycle events.
Android Specific Features
You can invoke "native" Android code from Codename One without breaking the portability of Codename One. Follow the native code section in the developer guide to understand how this can be accomplished, you can also see the how do I video tutorial on the subject. You can also add things to the manifest etc. if required by your native code.
In Part II of this series, we'll start using the porting tool and migrate the initial application logic.
Opinions expressed by DZone contributors are their own.