(For more resources on Android, see here.)
I guess you cannot wait anymore to test your new development environment. So why not compile and deploy elementary samples provided by the Android NDK first to see it in action? To get started, I propose to run HelloJni, a sample application which retrieves a character string defined inside a native C library into a Java activity (an activity in Android being more or less equivalent to an application screen).
Let's compile and deploy HelloJni project from command line using Ant:
$ cd $ANDROID_NDK/samples/hello-jni
android update project –p .
(Move the mouse over the image to enlarge.)
$ ndk-build
$ ant install
The result should look like the following extract:
$ adb shell
# am start -a android.intent.action.MAIN -n com.example.hellojni/com.example.hellojni.HelloJni
We have compiled, packaged, and deployed an official NDK sample application with Ant and SDK command-line tools. We will explore them more in later part. We have also compiled our first native C library (also called module) using the ndk-build command. This library simply returns a character string to the Java part of the application on request. Both sides of the application, the native and the Java one, communicate through Java Native Interface. JNI is a standard framework that allows Java code to explicitly call native C/C++ code with a dedicated API.
Finally, we have launched HelloJni on our device from an Android shell (adb shell) with the am Activity Manager command. Command parameters passed in step 8 come from the Android manifest: com.example.hellojni is the package name and com.example.hellojni. HelloJni is the main Activity class name concatenated to the main package.
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.example.hellojni" HIGHLIGHT
android_versionCode="1"
android_versionName="1.0">
...
<activity android_name=".HelloJni" HIGHLIGHT
android_label="@string/app_name">
...
Automated build
Because Android SDK, NDK, and their open source bricks are not bound to Eclipse or any specific IDE, creating an automated build chain or setting up a continuous integration server becomes possible. A simple bash script with Ant is enough to make it work!
HelloJni sample is a little bit... let's say rustic! So what about trying something fancier? Android NDK provides a sample named San Angeles. San Angeles is a coding demo created in 2004 for the Assembly 2004 competition. It has been later ported to OpenGL ES and reused as a sample demonstration in several languages and systems, including Android. You can find more information by visiting one of the author's page: http://jet.ro/visuals/4k-intros/san-angeles-observation/.
To test this demo, you need to follow the same steps:
As this application uses OpenGL ES 1, AVD emulation will work, but may be somewhat slow!
You may encounter some errors while compiling the application with Ant:
The reason is simple: in res/layout/ directory, main.xml file is defined. This file usually defines the main screen layout in Java application—displayed components and how they are organized. However, when Android 2.2 (API Level 8) was released, the layout_width and layout_height enumerations, which describe the way UI components should be sized, were modified: FILL_PARENT became MATCH_PARENT. But San Angeles uses API Level 4.
There are basically two ways to overcome this problem. The first one is selecting the right Android version as the target. To do so, specify the target when creating Ant project files:
$ android update project –p . -–target android-8
This way, build target is set to API Level 8 and MATCH_PARENT is recognized. You can also change the build target manually by editing default.properties at the project root and replacing:
target=android-4
with the following line:
target=android-8
The second way is more straightforward: erase the main.xml file! Indeed, this file is in fact not used by San Angeles demo, as only an OpenGL screen created programmatically is displayed, without any UI components.
Target right!
When compiling an Android application, always check carefully if you are using the right target platform, as some features are added or updated between Android versions. A target can also dramatically change your audience wideness because of the multiple versions of Android in the wild... Indeed, targets are moving a lot and fast on Android!.
All these efforts are not in vain: it is just a pleasure to see this old-school 3D environment full of flat-shaded polygons running for the first time. So just stop reading and run it!
Android SDK includes tools which are quite useful for developers and integrators. We have already overlooked some of them including the Android Debug Bridge and android command. Let's explore them deeper.
You may have not noticed it specifically since the beginning but it has always been there, over your shoulder. The Android Debug Bridge is a multifaceted tool used as an intermediary between development environment and emulators/devices. More specifically, ADB is:
ADB shell is a real Linux shell embedded in ADB client. Although not all standard commands are available, classical commands, such as ls, cd, pwd, cat, chmod, ps, and so on are executable. A few specific commands are also provided such as:
logcat
|
To display device log messages
|
dumpsys
|
To dump system state
|
dmesg
|
To dump kernel messages
|
ADB shell is a real Swiss Army knife. It also allows manipulating your device in a flexible way, especially with root access. For example, it becomes possible to observe applications deployed in their "sandbox" (see directory /data/data) or to a list and kill currently running processes.
ADB also offers other interesting options; some of them are as follows:
pull <device path> <local path>
|
To transfer a file to your computer
|
push <local path> <device path>
|
To transfer a file to your device or emulator
|
install <application package>
|
To install an application package
|
install -r <package to reinstall>
|
To reinstall an application, if already deployed
|
devices
|
To list all Android devices currently connected, including emulators
|
reboot
|
To restart an Android device programmatically
|
wait-for-device
|
To sleep, until a device or emulator is connected to your computer (for example,. in a script)
|
start-server
|
To launch the ADB server communicating with devices and emulators
|
kill-server
|
To terminate the ADB server
|
bugreport
|
To print the whole device state (like dumpsys)
|
help
|
To get an exhaustive help with all options and flags available
|
To ease the writing of issued command, ADB provides facultative flags to specify before options:
-s <device id>
|
To target a specific device
|
-d
|
To target current physical device, if only one is connected (or an error message is raised)
|
-e
|
To target currently running emulator, if only one is connected (or an error message is raised)
|
ADB client and its shell can be used for advanced manipulation on the system, but most of the time, it will not be necessary. ADB itself is generally used transparently. In addition, without root access to your phone, possible actions are limited. For more information, see http://developer.android.com/guide/developing/tools/adb.html.
Root or not root.
If you know the Android ecosystem a bit, you may have heard about rooted phones and non-rooted phones. Rooting a phone means getting root access to it, either "officially" while using development phones or using hacks with an end user phone. The main interest is to upgrade your system before the manufacturer provides updates (if any!) or to use a custom version (optimized or modified, for example, CyanogenMod). You can also do any possible (especially dangerous) manipulations that an Administrator can do (for example, deploying a custom kernel). Rooting is not an illegal operation, as you are modifying YOUR device. But not all manufacturers appreciate this practice and usually void the warranty.
Using the information provided, you should be able to connect to your phone like in the good old days of computers (I mean a few years ago!) and execute some basic manipulation using a shell prompt. I propose you to transfer a resource file by hand, like a music clip or a resource that you will be reading from a future program of yours.
To do so, you need to open a command-line prompt and perform the following steps:
.
The command named android is the main entry point when manipulating not only projects but also AVDs and SDK updates. There are few options available, which are as follows:
-p
|
The project path
|
-n
|
The project name
|
-t
|
The Android API target
|
-k
|
The Java package, which contains application's main class
|
-a
|
The application's main class name (Activity in Android terms)
|
For example:
$ android create project –p ./MyProjectDir –n MyProject –t
android-8 –k com.mypackage –a MyActivity
-p
|
The project path
|
-n
|
To change the project name
|
-l
|
To include an Android library project (that is, reusable code). The path must be relative to the project directory).
|
-t
|
To change the Android API target
|
There are also options to create library projects (create lib-project, update lib- project) and test projects (create test-project, update test-project). I will not go into details here as this is more related to the Java world.
As for ADB, android command is your friend and can give you some help:
$ android create project –help
Command android is a crucial tool to implement a continuous integration toolchain in order to compile, package, deploy, and test a project automatically entirely from command line.
With adb, android, and ant commands, you have enough knowledge to build a minimal automatic compilation and deployment script to perform some continuous integration. I assume here that you have a versioning software available and you know how to use it. Subversion (also known as SVN) is a good candidate and can work in local (without a server).
Perform the following operations:
Do not forget to check command results using $?. If the returned value is different from 0, it means an error occurred. Additionally, you can use grep or some custom tools to check potential error messages.
A free monkey to test your App!
In order to automate UI testing on an Android application, an interesting utility that is provided with the Android SDK is MonkeyRunner, which can simulate user actions on a device to perform some automated UI testing. Have a look at http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html .
To favor automation, a single Android shell statement can be executed from command-line as follows:
adb shell ls /sdcard/
To execute a command on an Android device and retrieve its result back on your host shell, execute the following command: adb shell "ls / notexistingdir/ 1> /dev/null 2> &1; echo $?" Redirection is necessary to avoid polluting the standard output. The escape character before $? is required to avoid early interpretation by the host shell.
Now you are fully prepared to automate your own build toolchain!