Android/Android SDK
The Android Software Developer Kit is what you use to develop Android applications. You get it from here.
The difference between a GUI and a command line
[edit | edit source]The SDK includes a plugin for use with the Eclipse IDE, as well as command-line tools that can be invoked via an Ant build script.
Most developers seem to prefer GUI tools. However, this makes it difficult to choose a different IDE or text editor. Also, complex builds require the execution of custom scripts at build time, and only the command line offers the flexibility to cope with this.
Native Code
[edit | edit source]Android apps do not have to be written entirely in Java. It is possible to include C/C++ code and compile it with the Native Development Kit (NDK). This code then interfaces with the Java code through the Java Native Interface (JNI), of which the Dalvik virtual machine includes a (mostly) complete implementation.
When you might want to use the NDK:
- Port C/C++ code from another platform.
- Java code is too slow—but beware: “premature optimization is the root of all evil” (variously attributed to Donald Knuth or Tony Hoare). Do actual testing to determine where the slow parts of your code are, before trying to speed them up: the performance bottlenecks are often not where you think they are.
- Allocate more memory than the 20MB or so permitted for your Java heap.
Reasons not to use the NDK:
- Your compiled code ends up being architecture-specific. Sure, you can include alternative versions for, say, both ARM and MIPS to cover the likely bases for now, but what happens if Intel’s Atom efforts pay off, and future devices make more use of x86 chips?
- Debugging is hard. Instead of seeing a nice Java exception traceback in the logcat, pointing to the exact source line where the error occurred, you get a crash register dump. However, it is possible to narrow down the point of the error through the standard expedient of outputting debug messages at strategic points in the code (see Logging, below).
Better JNI glue
[edit | edit source]The standard Android-provided jni.h
makes it slightly awkward to call JNI routines. You can improve this by processing jni.h
through JNIGlue, which generates more convenient static inline wrapper routines. For example, instead of
const jclass SystemClass = (**env).FindClass(env, "java/lang/System");
, you can do
const jclass SystemClass = JNFindClass(env, "java/lang/System");
Logging
[edit | edit source]In Java code, you can write messages to the logcat using either the Log class, or simply write to the standard Java System.err diagnostic stream or System.out output stream. In the first case, you can set the logging level and the “tag” string used to prefix your messages; in the second case, the level is always warning (W), and the tag is always “System.err”, and in the last case, the level is info (I) and the tag is “System.out”.
In native code, the usual stdio streams of stdout and stderr are defined, but do not work—certainly trying to write to stdout or stderr not only does not display messages anywhere, it can lead to strange crashes elsewhere in your code.
Instead, you can use the native logging library. There is no public documentation for this, but the routines are in the android/log.h
header file that you can include in your C/C++ code. Also in your Android.mk
for building the native code, add -llog
to the definition of your LOCAL_LDLIBS
variable.
Messages written to the logcat in this way look like this:level/tag(pid): text or, like this: W/System.err( 1288): test app successfully started
The log levels are enumerated in android/log.h
, and the corresponding single-letter codes that appear in the messages, are:
code | char |
---|---|
ANDROID_LOG_UNKNOWN | message does not appear |
ANDROID_LOG_DEFAULT | |
ANDROID_LOG_VERBOSE | V |
ANDROID_LOG_DEBUG | D |
ANDROID_LOG_INFO | I |
ANDROID_LOG_WARN | W |
ANDROID_LOG_ERROR | E |
ANDROID_LOG_FATAL | F |
ANDROID_LOG_SILENT | S |
GCC Extensions
[edit | edit source]The C and C++ compilers included with the NDK are built from GCC, so you have access to the usual GCC capabilities. For example, you can do the C99 #include <stdbool.h>
and use the bool type, with values true and false, in conditional expressions in your code. You can enable more general C99 capabilities by putting a line like this in your Android.mk:
LOCAL_CFLAGS += -std=c99
A possible example of setting up Android development in Ubuntu
[edit | edit source]This is a walkthrough of a typical setup of Android development in Ubuntu 18.04 LTS.
Then following the
Android Studio for Linux installation instructions
( https://developer.android.com/studio/install#linux )
( https://linuxize.com/post/how-to-install-android-studio-on-ubuntu-18-04/ )
( https://askubuntu.com/questions/634082/how-to-install-android-studio-on-ubuntu )
One approach to installing Android Studio: Open a terminal window in Ubuntu 18.04 with Ctrl+Alt+T then run
sudo add-apt-repository ppa:lyzardking/ubuntu-make
sudo apt update
sudo apt install ubuntu-make
umake android
then add a shortcut to the "~/.local/share/umake/android/android-studio/bin/studio.sh" file to the desktop.
One approach to installing Android Studio:
(Alas, doesn't yet work with Ubuntu 18.04)
Open a terminal window in Ubuntu with Ctrl+Alt+T
then run
snap install ubuntu-make --classic
umake android
Another approach to installing Android Studio:
- From https://developer.android.com/studio download "Android Studio for Linux".
- [FIXME: then what? See https://askubuntu.com/questions/634082/how-to-install-android-studio-on-ubuntu for more details.]
- ...
A possible example of setting up Android development
[edit | edit source]This is a walkthrough of a typical setup of Android development.
The IDE will be Eclipse because it is so flexible. The latest edition is downloaded, it is the one for Java development and plugin development) This is unzipped in a user chosen directory, and we try to execute it. Hopefully it does, e.g. fortunately we didn't choose the 64 bit version of eclipse when the 32 bit of Mint was installed.
A little Hello World java program will be written, to see if the eclipse IDE has a working Java compiler. At least the Java runtime should be working, because Eclipse wouldn't run otherwise. If not, go to synaptic or the mint applications loader and find a java runtime, e.g. openjdk 7 in 2013.
The next step is to get the android SDK. In November 2013, it was the r22 build, found at [1], and this is downloaded and unzipped. It might not work if you have a 64 bit Mint environment though, maybe a Red Hat environment would. To get it working in this case, you have to execute the emulator and see what it says.
If it says something like there is no file or directory called .. tools/emulator , then likely you don't have a 32 bit environment installed, so get the libc 32 bit environment from the Synaptic Package Manager.
If you aren't the administrator, open a terminal first, run su, then type the administrator password (the first user created when Linux Mint was installed). Then type synaptic, and then install libc6-i386.
Keep running the emulator and installing the libraries it needs, e.g. lib32stdc++6.
Something else won't work either, which is the aapt build tool in the build-tools folder from the Android SDK, which requires the 32 bit version of the zlib library, lib32z1. It shows up later, when you find that the generated R class for your android application doesn't generate automatically when editing your project, and everything R.xx is underlined in red.
Run the ./tools/android exec, it should actually work even if there is no 32 bit libs. This is to get your selected Android platform/platforms loaded, e.g. 4.4 kitkat, or 4.3 jelly bean, or 2.2 froyo, and also down in the Extras folder at the bottom, the latest android support package is there, because this gives you backward compatibility of an application written with a set of API's (ex:, using an Android Froyo API in an Android Honeycomb application, if the support library is included in your project. Also you need the ARM system image as a minimum, and maybe the Intel one, but each image makes the download longer, and you can easily end up with 1 GB of development tools (or more) just to get your Hello World application on android.
Install the plugin in Eclipse, by running it from your specified path in Windows or Mac OS X and going to the Help option, and install the required packages, then at the top, add in a new software repository by clicking the "Add.." button, and pasting this URL in the "Location" field, [2]. Then choose the Android Development Plugin (or ADT, for shorthand), and the NDK, if you want to compile native C or C++ code in your Android applications
After this, create a blank activity in your Android project, and run it
This requires setting up by clicking under the "Window" menu item in Eclipse and "Android Virtual Device Manager", and then choose a low grunt virtual device like Nexus One, so that you don't grow too old waiting for the virtual device to start. Click the second tab in the AVD manager, and then select Nexus One from the list on the left, and the "Create AVD" button on the right becomes enabled, and then it creates a virtual device with the ARM system image and whatever level of Android API, but beware of using "Native OpenGL" because the 32 bit libraries for these may not be loaded, and it will still let you create your AVD, but it will not work.
After this, you can try to get a calculator project going, but don't do the programming one from Google, just use the layout editor for the MainActivity.xml file, as you can have 4 buttons in one horizontal layout, copy the layout, and paste it to get the other rows. You can also set the onClick method for all the buttons by Ctrl-clicking to select more than one of the buttons, and then right click in the Outline view over a highlighted button, and choose the menu item "Other property.." and choosing "OnClick", and typing the method name to receive e.g. onClick buttonPressed.
Then create a public method in the MainActivity.java file, called public void buttonPressed(View v)
, and handle any button clicks by identifying the button using the button's label. (Cast the v passed in into a Button object first)
Happy Android programming, and may the Google Play Store success be with you.