Android native development without Java

Lately I've been revisiting options for writing native Android applications. For the last six months I've been working on some cross platform projects, kind of hoping that the Android browsers would improve to a level where writing and deploying a javascript-based application (or compile-to-javascript if you're using Coffeescript like I am) for the Android platform would be a real option. Sadly, that still seems a long way off. Android's native language is Java running on the Dalvik virtual machine. When targeting Android you will write code in a language that compiles into JVM byte code (the assembly language for the Java Virtual Machine - JVM). The Android SDK takes the JVM byte codes (typically .class files) and translates them into their Dalvik equivalents, and does additional transformation of certain kinds of resources. All of this is stuffed into an .apk file which is how applications are distributed to Android devices.

So to target Android devices, you need to either write your applications in Java, or a language that compiles into Java source code or JVM byte code. Java is the first language of Android. Like most programming languages, Java has its good and bad sides. Today there are many languages targeting the JVM, like Scala, Cloure, Kawa, JRuby and many more. And fortunately some of these even support Android. When targeting Android - which typically runs on mobile phones - package size and execution speed (and battery usage) quickly becomes an issue. Some of the languages and their toolkits have improved to a level where deploying to Android devices is a real option.

Another thing to be aware of; When talking about programming languages below, I am mostly focusing on syntax, not the standard libraries that typically come with the language. A small language like Clojure typically has a payload of just below 2MB if you need "the full" language and libraries. The reality today is that if you want to target Android devices, you need to use the built in Android libraries, and there are practical limitations in how much of their standard libraries the languages can carry over to Android devices (unless those libraries are very small of course).

I recently took another look at the JVM Android landscape and this is what I found;

Mirah is still around. It's Ruby programming for Android. If Ruby is your preferred language this may be a good choice. Mirah also carries very little overhead; that means that your apk size will be real small (starting around 16KB for a minimal application). It also means that beside the Ruby syntax, you probably should not count on your favorite Ruby library and/or flexible data structures are available. Even if the syntax is Ruby, your environment is Android, and Mirah is a very thin wrapper on top of the Android libraries, and could probably be considered java with a ruby syntax (which may be a good thing). While Mirah has been around for a while, tooling and documentation seems to be lacking, and many of them are outdated.

Scala has had decent Android support for a while. My knowledge about Scala is superficial so I will not make too many comments about it, other than to note that when compiling for Android, the manage to get their apk package size down to around 10KB, but the compiling process is also famous for being painfully slow.

Clojure also has decent Android support, but so far the apk sizes created make it unsuitable for general applications to run on any (-body's) device. A minimal Android application on Clojure typically start at 1.7MB, although I've read reports that die hard Clojure proguard experts have managed to get it down to the "hundreds of KB" level. That's still a long way off compared to the rest, so I personally do not consider Clojure an alternative for Android development today.

I recently found Kawa, a JVM based Scheme language, which seems to offer a decent language (Scheme, a Lisp variant) together with a reasonable apk package size. In my own tests a minimal "hello world" style application in Kawa compiles down to an apk file of 49KB. I just recently started developing in Kawa so I am unable to comment on what those 49KB give us. If it's not really needed, I guess more proguard tweaking will make the apk smaller. Alternatively, there is a minimal standard library in there making development less painful than having to deal with java syntax for simple data structures and similar. Time will tell. But from my point of view, 50KB is not too large to get started, so unless there are other issues that will make the payload increase significantly for normal development, Kawa is looking very promising.

For my own sake, I will be trying to use Kawa for my next project, and mix in with native Java where it makes sense.

Ubuntu 12.04 with open source ATI driver

It's no secret; graphics drivers continue to be a PITA in linux. While Nvidia and AMD have their own proprietary drivers which give decent support for some combinations of linux distribution version, there is always something which just does not work right (does not run with recent beta releases of distributions, does not support multiple monitors or something else). A few years ago I gave up a trusty old Nvidia adapter after AMD promised to support the development of a decent open source driver, and traded it in for a similarily trusty old AMD adapter which by then at least had an open source driver; a Radeon HD 4650 (technically an ATI RV730 PRO chipset). It wasn't great, but at least things were improving.

Ubuntu has a community page on the state of the open source Radeon driver on https://help.ubuntu.com/community/RadeonDriver, which again points to the xorg-edgers PPA. When running the "bleeding edge" ppa drivers, it worked ok.

At least until a new beta came along; When the Ubuntu 12.04 beta arrived, I installed it, and my bleeding edge drivers got disabled by default. The default drivers for my card that came with Ubuntu 12.04 worked poorly. It never crashed, but there were visible defects (fonts and bitmaps suddenly becoming garbage in non-focused windows, only mostly to correct itself when window came in focus again) and performance over time became sluggish (nothing that a compiz --replace did not fix, but still very annoying). Since the xorg-edgers PPA had not been updated to support 12.04 yet, installing the bleeding edge drivers was more work than I was willing to suffer.

Having written all this, I am happy to report that when I now recently reinstalled the xorg-edgers PPA drivers on my Ubuntu 12.04 system, the visible defects were gone and performance was noticeably faster. I have not seen any performance degradation yet either (but have not used it for very long either). Assuming nothing else surfaces, it looks like my system can be used as is, until Intel's Ivy Bridge system are available at a decent price.

Brief comment on Intel; I believe the open source drivers for the Intel graphics chipsets (HD 3000 and future releases) already have great quality, at least on one of my laptops. For my desktop system however, which is not even a Sandy Bridge system, embedded Intel graphics were not available, so even while Intel's HD 3000 probably would be sufficient, it was not an option when I built my current desktop computer.

Linux GUI confusion; Ubuntu 11.10 Oneiric, Unity and Gnome 3

I've tried them all; Windows, Mac OSX and Linux. Windows sucks for software development, but if you have to use it and are not locked into the .Net/CLR environment using Visual Studio, make sure you install Cygwin, which makes it kind of useable for some tasks (Emacs, Perl, Clojure and more). I tried going with the Mac OSX momentum as well; it has a solid Unix foundation which makes most development comfortable if you are coming from the Linux side of things. Unfortunately, it is also quite often just different enough the traditional Linux setups, so you most often need to install tons of other stuff in addition to the standard things that comes bundled with it. So pretty soon you risk having multiple versions of perl and other commonly used tools, essentially a whole "tree" of "non-standard" utilities to keep up with the stuff needed for using the latest versions of whatever tool needed. The thing that kept me from settling in was the lack of a decent full screen mode (maximized Window mode; this is from a couple of years back) and the fact that it never felt like Emacs was a first class passenger on Mac OSX (I went to hell and back trying to get it to recognize my favourite bitmap font; without success). So in the end, I wasted a lot of time (again) to get my Linux GUI setup decent, and it was for a couple of years (Ubuntu Linux 10.10 and 11.04).

A couple of years later, I'm sad to say that the state of the Linux GUI is still sad. With the right combination of laptop and age, you may very well be able to have a great functional stable GUI. Unfortunately "right combination" usually means "not too old and definitively not too new". On the "too new" side, it's mostly possible to get things working by installing development packages etc, but that's definitively not for the newbies out there and require skill, knowledge and a lot of effort. On the "too old" side of things, you may be SOL, thanks to proprietary drivers (in my case nVidia) no longer being supported.

Even more maddening is the fact that the GUIs themselves seem to have gone from "stable, functional and nice looking", to "unstable, barely functional, but possibly looking better than ever". A couple of years ago I moved from KDE to Gnome 2, after years of frustration with getting a stable networking applet running under KDE, shortly after KDE had it's own "evolution" from KDE3 to KDE4 (not a great success story either at that time). Switching to Gnome 2 gave me great hopes for the linux GUI side of things; it just worked and looked great.

Fast forward until the last few months; Gnome 2 is considered "to be discontinued", and we've gotten even more spoiled with eye candy, transparency and more on all platforms. Ubuntu has launched their own project, Unity, and Gnome is working on upgrading to Gnome 3. Both these bring entirely new GUI paradigms to the Linux desktop, and common to both of them seem to be focusing on the "laptop/tablet" factor only. That means that if you need to run applications full screen on a small screen, the new paradigms work ok; it takes some getting used to, but nothing major. But on our "old" (by now industry standard in software development) big screen, and even multiple big screen, setups, the new paradigms offered simply aren't ready.

Unity, running on top of Gnome 3, tries to go in the direction of OSX it seems, forcing the menu bar to always appear on the top of the screen. Sadly, a lot of Linux users are used to "focus follows mouse" instead of "click to focus", which means that unless your application is nailed to the top of your screen, you need to navigate to the top screen menus for your application without the mouse passing over any other application (which would activate another set of menus). Workaround are either to activate "click to focus", or run your applications full screen. The upshot is that Unity offers great keyboard navigation shortcuts, so maybe I will finally be able to adjust myself to accept "click to focus" (and use the mouse even less overall).

The Gnome Shell offers an alternative to Unity, also running on top of Gnome 3. I haven't made my mind up yet which one I prefer; I'm trying to get used to both.

Gnome 3 (or possibly the Gnome Shell part of it in a couple of cases) add a lot more eye candy.But also seem to target exclusively (at least initially) the laptop/tablet form factor. And they are even more ambitious as far as "revolutionizing" the desktop metaphors go and remove well known entities such as minimize and maximize buttons, and state the concept of workspaces are probably better anyway. Workspaces are "secondary desktops"/screens whatever that you can easily move between by pressing ctrl-alt-arrow-up and -down. That works fine, at least until you are on your dual screen setup again. Then notice that the workspace scrolling (up and down) only happens on one monitor; the workspace does not switch on the second monitor. At least Unity managed to keep the expected "workspaces" behaviour.

Generally, Gnome 3 (meaning both Unity and the Gnome Shell) seems to have messed up Alt-Tab for switching Windows. Alt-Tab now switches applications, so if you need to go to a certain window in an application, you first have to Alt-Tab to the proper application, then wait a second or two for the Application to show it's windows, and then keep tabbing to the right window. Alt-` (the button above tab) allows you to switch windows inside the current running application, but not to windows in other applications. For at least some of these changes, workarounds are supposedly available but I haven't gotten them working yet.

I've done most of my testing for the last couple of months on alpha and beta versions of Ubuntu 11.10 Oneiric, but unfortunately the improvements seem to be slow arriving, making me doubt whether any new desktop will be decent to launch sometime in October. In addition to the issues I've mentioned already, it also seems a lot of the desktop customization stuff seem to have disappeared from Gnome 3. Simple things, such as modifying system fonts and sizes and/or various theme/icon settings does not seem to be included in System Settings anymore. There is a package with a tool that has such settings (gnome-tweak-tool), but based on the type of experience I got used to from Gnome 2, that tool looks kind of foreign and a lot of the settings related to themes etc simply do not work.

Having said all this, I still believe Linux (and the people and movements behind it) offer a much more compelling overall development experience that most other systems, and I can take a lot more pain before giving up, but here's hoping and praying that Linux based groups will manage to pull through and deliver a great experience in the end. Unfortunately, I still the "Linux Desktop" for "normal users" is still a couple of years ahead. Based on the progress the last five years, it could be even longer, but I'm keeping my fingers crossed that it will be fixed long before that.

And finally, some notes to myself below on what I need to do to get a decent Ubuntu 11.10 Oneiric system going:

Alt-Tab changes: Supposedly, there is a workaround for getting rid of the awful Alt-Tab changes, but I haven't gotten it working on my system yet (Unity does not allow Shell Extensions at all; Gnome Shell allows me to install and enable it using the gnome-tweak-tool, but then Alt-Tab simply does nothing). If you want to try, google gnome-shell-extensions-alternate-tab .

Atheros wireless drivers: This one seems to be haunting Linux. For older type cards (lspci outputs "Intel Corporation Ultimate N WiFi Link 5300") it seems the full series of Oneiric alphas, and betas so far, has a regression as far as cryptography in the "iwlagn" driver goes. To work around it and get decent wifi speed again, add "options iwlagn swcrypto=1" to /etc/modprobe.d/iwlagn.conf . For newer cards, add "options ath9k nohwcrypt=1" if you're having really slow wifi. Hopefully these will be nailed (again) before the final Oneiric release.

Clojure CLR/.Net on Windows

My latest work requires me to get more intimate with development on the Windows platform again, and I'm taking this opportunity to explore Windows CLR and .Net using Clojure, or more correctly Clojure-CLR, the version of Clojure that is hosted on the .Net platform. Unfortunately, there is a lot less documentation about Clojure-CLR, so it probably is a bit harder to get started.

Downloading and building clojure-clr

You can get clojure-clr from https://github.com/richhickey/clojure-clr , where you can either download it as a pre-compiled binary, or download/checkout the source and build it yourself. If you want to build it yourself, make sure you download the lib.zip file as well; it contains the library dependencies you need for building from source (in addition to the .Net 3.5 or 4.0 SDK).

To build clojure-clr, open the Visual Studio "solution" file Clojure/ClojureCLR.sln . After successful building, you will find the binaries inside bin/4.0/Release (or 3.5 if you build against dotNet 3.5, and/or Debug instead of Release if you build a debug release). After building, you can fire up Clojure.Main.exe to have the famous REPL (http://en.wikipedia.org/wiki/REPL) up and running.

Running clojure-clr

Windows isn't well known for it's rich selection of command line shells, probably simply because they aren't used all that much. Doing simple scripting and programming in REPL style environments requires some method of entering commands and getting output, and the command line shells are usually the most "universal" method of doing this. Windows offers the default cmd.exe for all users. The Windows Powershell is also available, but possibly not installed by default. Both of these offer limited choices (if any) as far as resizing goes, including both window size and font selections and sizes. And the default font selections in Windows are usually too large and almost always in bold.

Having been somewhat spoiled from the relatively rich selection of choices in the Linux environment, I installed Cygwin (Unix toolset for Windows - http://cygwin.com/) and had a rich shell available (I selected mintty), which allows for full and easy resizing of windows and font sizes. Unfortunately, due to the way Windows console applications work by default on Windows, there was an issue with arrow keys and command line editing inside the Clojure REPL. In a REPL you need command line editing and history to work.

It seems the author of mintty has created a fix which works great with Clojure on Windows, see http://groups.google.com/group/mintty-discuss/browse_thread/thread/1f9cf... . If you start Clojure inside conin ("C:\>conin Clojure.Main.exe"), command line works great, and you get a rich command REPL environment for developing using clojure-clr.

Clojure Hello World in Windows

Microsoft has been in catch-up mode for the last decade, and unfortunately their API/development platforms shows. If you want to implement a "native" Windows GUI application today, the choices for the .Net/CLR platform is either Windows Forms (Forms) of the Windows Presentation Framework (WPF). While a lot can be said for either framework, the usual recommendation is to use WPF. I've managed to put together examples of two simple hello world style examples below for both frameworks. The first one, using Windows Forms, is pretty straightforward.

(import '(System.Reflection Assembly))
(Assembly/LoadWithPartialName "System.Windows.Forms")
(ns helloworld
	(:import (System.Windows.Forms MessageBox)))
(MessageBox/Show "Hello world")

The second hello world example is a bit more complex. It starts a Windows application, opens an empty main windows and changes the title in the window to "Hello world". As the code demonstrates, it is not as straightforward, partly because it does more (starts the GUI app in it's own separate thread), and partly because WPF requires a larger footprint to get a minimum application up and running.

(import '(System.Reflection Assembly))
(Assembly/LoadWithPartialName "PresentationFramework")
(Assembly/LoadWithPartialName "PresentationCore")
(Assembly/LoadWithPartialName "WindowsBase")
(ns hellowpf.core
	(:import (System.Windows Application Window))
	(:import (System.Windows.Threading  Dispatcher DispatcherPriority))
	(:import (System.Threading ApartmentState ThreadStart Thread)))

(defn gui-main []
	(let [app (Application.)
				mainwin (Window.)]
		(.set_Title mainwin "Hello world")
		(.Run app mainwin)))

(defn wpf-eval
	[uithread repl-ns-sym data]
	(.Invoke (Dispatcher/FromThread uithread) DispatcherPriority/Normal
					 (gen-delegate Action []
												 (clojure.main/with-bindings
													 (in-ns repl-ns-sym)
													 (eval data)))))

(let [threaddelegate (gen-delegate ThreadStart [] (gui-main))
			uithread (doto (Thread. threaddelegate)
								 (.SetApartmentState ApartmentState/STA)
								 (.Start))]
	(clojure.main/repl :eval (partial wpf-eval uithread 'hellowpf.core)))

While the Forms example can be run repeatedly from within the Clojure REPL environment, the WPF application can not. It seems related to the fact that the System.Windows.Application instance can only be used and instantiated once within an interactive environment such as the REPL. While this may not be a big problem for running the app as a "standalone app", it certainly does not make it very practical to work with such applications from the REPL environment, unless you do not mind restarting the Clojure REPL every time. According to answers I've found through Google, the Forms API seems to offer simple support for restarting an application within a process, it seems the same functionality is lacking for WPF applications. It may very well be that it is and should be possibly, but based on my finding it's not very easy. If somebody wants to clue me in on how I can restart a WPF application without restarting the process, feel free to write a comment.

Pages

Subscribe to Marius Kjeldahl's homepage RSS