50 Android Hacks (2013)
Chapter 8. Interacting with other languages
Android applications are coded mainly in Java. Officially, Android also supports C/C++ using the Android NDK (Native Development Kit). But is it possible to develop applications using other programming languages? In this chapter, we’ll analyze the other possibilities.
Hack 33 Running Objective-C in Android: Android v1.6+
During the summer of 2011, my company released an iOS game called Shaman Doctor. The game was developed using cocos2d-iphone, an iOS library. The cocos2d-iphone library is coded in Objective-C, but there are a lot of forks that offer the same API in other programming languages. One of the most active forks is cocos2d-x. Instead of using Objective-C, cocos2d-x uses C++, and the most interesting thing about this project is that the API looks like Objective-C. To get an idea of what the Cocos2d-x team has created, take a look at the following code:
As you might have noticed, the API is exactly the same, but to port a game from cocos2d-iphone to cocos2d-x you would need to port all your Objective-C code to C++, which is a boring task.
When I started looking for alternatives, I found a library called Itoa created by Dmitry Skiba. To understand what Itoa is capable of, let me quote its documentation (see section 33.5):
[Itoa] is a cluster of open-source projects hosted on GitHub that implement compiler, build scripts and various libraries to allow building Android’s apk from Objective-C source files.
Itoa’s main purpose is more than just running Objective-C in Android; it’s to magically convert an iOS application to an Android one. While its main feature is far from complete, the fact that it allows running Objective-C in Android is real.
What we’ll do in this hack is port a simple Objective-C library called TextFormatter. This means that we’ll run the Objective-C code in Android without needing to modify it.
Foundation: The NDK And Objective-C
Itoa makes heavy use of the Android NDK. You’ll need to understand how the NDK works to understand what comes next. If you have never used the Android NDK, you can read about it in Android in Action, Third Edition (W. Frank Ableson et al., Manning Publications, 2011). You’ll also need to have a basic understanding of Objective-C.
33.1. Downloading and compiling Itoa
Compiling the Itoa library is quite easy. Just run the following from the command line:
chmod +X build-ndk.sh
This script will create a folder named itoa, fetch all subprojects, and build the NDK inside itoa/ndk. The resulting folder structure can be seen in figure 33.1. In other words, the script will first set up the tool chain and it’ll use it to compile all the subprojects, leaving the .so files inside a folder at /itoa/ndk/itoa/platform/arch-arm/usr/lib.
Figure 33.1. Itoa folder structure
33.2. Creating the modules
As in any ordinary NDK application, we’ll separate the code in modules. We’ll create a module called textformatter containing the library we want to port, and a second one called main, which will be in charge of the communication between Java and the TextFormatter class.
33.2.1. The ItoaApp.mk and the ItoaModule.mk files
In a way similar to how the Android NDK uses the Application.mk and the Android.mk make files, Itoa has the ItoaApp.mk and the ItoaModule.mk files.
Inside our Android project directory, we’ll create a folder called jni. This jni folder will contain two make files, ItoaApp.mk and ItoaModule.mk, and two folders to hold the modules—one folder for the textformatter module and a second one for the main module. Inside each module folder, we’ll create an ItoaModule.mk file. The resulting directory structure can be seen in figure 33.2.
Figure 33.2. Jni folder structure
Let’s take a look at what we’ll place inside the ItoaApp.mk and ItoaModule.mk files. In the ItoaModule.mk make file, we’ll point to the module’s ItoaModule.mk files relative to the jni folder. The content is the following:
THIS_PATH := $(call my-dir)
The ItoaApp.mk file contains more interesting information. The content is the following:
The default settings for the ItoaApp.mk file are enough for what we want to create. Since we don’t want to create an Android APK from the Objective-C code, we need to turn on the library mode . The second setting is to set the path where the .so files will be saved .
33.2.2. The textformatter module
The library to port is very simple. It only has a class method that returns an NSString *. The Objective-C code for this library is comprised of a .h file and a .m file. Here’s the code:
As you can see, the library doesn’t need any modification. It’s just a .h and .m like you would use in an Objective-C application. Now let’s see how to configure the ItoaModule.mk file to compile this. Itoa NDK build scripts were derived from Android NDK, but they were refactored. For example, the ItoaModule.mk file renames all the LOCAL_* variables to MODULE_*. The content of the make file is the following:
Very similar to Android NDK make files, right?
33.2.3. The main module
The main module holds two source files:
· JNIOnLoad.cpp, where we’ll use the JNI_OnLoad method
· main.mm, where we’ll link JNI calls with the TextFormatter implementation
Let’s create the JNIOnLoad.cpp file first:
Because the virtual machine calls the JNI_OnLoad method when the native library is loaded, it’s a great place to make the initialization needed by Itoa.
Now let’s complete the main.mm implementation, which is the following:
In the previous example, we have a mixture of C, C++, and Objective-C in the same file. From the method signature, we can learn that the TextFormatter Java native call will get a String as a parameter and will return a String . Another interesting concept to learn here is that we can’t send the jstring we get as a parameter to the TextFormatter implementation directly. We need to convert the jstring to a char * and then convert that char * to an NSString * . After calling the TextFormatter implementation, we’ll get an NSString * that will need to be converted to a jstring. This is done by converting it to char * first, and using the env to be able to return a jstring .
The ItoaModule.mk file for main is the following:
Let’s talk about what the APP_SHARED_LIBRARIES is for . For that variable, we used the macro $(TARGET_ITOA_LIBRARIES), which means that the .so files located at $ITOA_NDK/itoa/platform/arch-arm/usr/lib will be included in the libs directory. If you check what’s inside that directory, you’ll notice there are more .so files than we actually need. Before building it, you’ll need to delete (or move) the following libraries from $ITOA_NDK/itoa/platform/arch-arm/usr/lib:
Now that we have all the native code in place, we need to compile all the .so files. Run this code
from the jni folder.
You can also use $ITOA_NDK/itoa-build -C /path/to/jni to avoid having to move to the jni folder.
After the compilation procedure finishes, we’ll get every .so file needed to run our Objective-C code in Android. In the next section, we’ll see how to call it from the Java layer.
33.3. Setting up the Java part
The Java part will hold an Activity class and a TextFormatter class with the native method. The Activity is the following:
The following is the TextFormatter Java code:
The most important part of this piece of code is understanding what libraries will get loaded inside the static block . They include the following:
· macemu: Contains emulation of some APIs used by objc4 and CoreFoundation libraries
· objc: objc4 runtime
· cf: CoreFoundation classes
· foundation: The Foundation library
· textformatter: Our TextFormatter library
· main: Our main library
When you run the application, you’ll see a TextView populated with a mixture of texts from the Java and Objective-C worlds.
33.4. The bottom line
Using Itoa to port Objective-C applications to Android might be a good idea, depending on the type of code you need to port. I’ve used it to port business logic from iOS to Android and also to port cocos2d-iphone games to Android. My recommendation is that you give it a try and decide if it would work for you.
33.5. External links
Hack 34 Using Scala inside Android: Android v1.6+
If you’ve never heard of Scala, it’s a multiparadigm programming language designed to integrate features of object-oriented programming and functional programming. Let’s look at some of the benefits of using Scala, instead of Java, in Android to create a project:
· Less verbose than Java.
· It can use existing Java code.
· Dealing with threads is easier than in Java.
Discussing the benefits of Scala over Java is beyond the scope of this book, but let’s look at what’s possible with Scala. In this hack, we’ll create a two-Activity application. One will be coded in Java and the other in Scala. This is a basic example we’ll use to understand how to compile an Android application with Scala code.
As you might know, Android builds code by compiling your Java classes to byte-code, and afterward that bytecode is converted to dex. To make Scala code work inside Android, we need a tool that does all of this:
· Converts Scala code to bytecode
· Processes the Scala standard library to minimize the app size
· Processes Java code
· Creates an APK
Believe it or not, there are a lot of ways of getting this done. From my personal point of view, the best tool is SBT with its Android plugin.
What is SBT? SBT stands for Simple Build Tool. It’s an open source build tool for Scala. Among its benefits:
· The project structure is similar to Maven.
· It manages dependencies using existing Maven and/or Ivy package repositories.
· It allows you to mix Scala and Java code.
What does the SBT Android plugin provide? The Android plugin is a script for creating a new Android project that SBT can compile. It also has several handy SBT targets for doing things such as packaging your app for the market and deploying to your device.
If we create a new Android application using the SBT Android plugin, we’ll get a project directory structure similar to figure 34.1.
Figure 34.1. SBT Android plugin project structure
Since SBT allows Java code as well, we’ll add our Java code inside src/main/java. Remember that, though Scala doesn’t need to place files on a certain folder depending of the defined package, Java does. In this hack, we’ll use com.manning .androidhacks.hack034 as our package, so we need to create a directory structure that respects that. The correct project structure for adding a second Java Activity can be seen in figure 34.2.
Figure 34.2. Project structure with Java code
Let’s look at the Activity done in Java and how it connects to the Scala Activity. Here’s the code:
Do we need to do anything different to call the Activity done in Scala? No, there isn’t anything special. We start the Scala Activity as any ordinary Activity .
Now let’s take a look at the Scala Activity code to see what’s there:
You can see that the Scala Activity’s code is 100% Scala. The Scala coded there comes from the demo application created by the SBT Android plugin. Take a closer look at how the content view is set . That line creates an anonymous subclass of the TextView, and with the help of an initializer block it calls the setText() method.
To run the application, we can launch SBT and execute the following:
Unfortunately, creating an APK takes a while. This two-Activity application takes me about one full minute to compile. You should know that this isn’t Scala’s fault. What takes so long is the ProGuard pass that goes through the Scala library and removes any unused part of it. To solve this issue, some developers add the Scala libraries to their developing device. There’s even an Android application that installs Scala on your device if it’s rooted.
34.1. The bottom line
Scala is gaining a lot of momentum in the Java world, and it’s also attracting interest in the community of Android developers. Learning a new language might feel time-consuming, but Scala is something that every Java developer should try.
34.2. External links