Intel
Your guide to mobile application development
Android on
To Architecture Intro to Android | The Android SDK | Developing for Android | GUI Development | The Android NDK | Developing for Android x86 | Debugging on Android | Intel Hardware Accelerated Execution Manager
A 9.9 Media Publication
Android on
Intel Architecture
Advanced
Intermediate
Beginner
Contents
01 Introduction Through the course of this booklet, you’d be able to develop an app for the Android platform and find relevant details to cater to the Intel x86 Android portfolio.
03 D evelop for Android All you need to know while developing for Android
05 Android NDK
Getting under the hood of Android and refining your app would need you to be familiar with native code.
07 Debugging on Android With every product comes troubleshooting.
02 Getting Started The Android SDK when paired with an IDE and API libraries, platform tools gives you a complete environment.
04 GUI Development User interface is a driving factor in the success of your app. Here are tips to stand out of the crowd.
06 Developing for x86
x86 is no longer restricted to PC. Here’s quick way to get started with Android for Intel devices.
> Your guide to mobile application development >
Android for X86 Editorial Assistant Editor Nash David Writers Ankit Mathur & Soham Mondal with inputs from Intel
Design Sr. Creative Director Jayan K Narayanan Sr. Art Director Anil VK Associate Art Directors Atul Deshmukh & Anil T Sr. Visualisers Manav Sachdev & Shokeen Saifi Visualiser Baiju NV Consulting Designer Vijay Padaya
brand Product Manager Arun Yadav Manager Online Shauvik Kumar Asst. Product Manager Kshitij Garg Cover Design Vijay Padaya
Š 9.9 Mediaworx Pvt. Ltd. No part of this book may be reproduced, stored, or transmitted in any form or by any means without the prior written permission of the publisher.
March 2013 Free with Digit. If you have paid to buy this book from any source other than 9.9 Mediaworx Pvt. Ltd., please write to editor@devworx.in with details
Chapter 1
Introduction Through the course of this booklet, you'd be able to develop an app for the Android platform and also find the relevant details to cater to the Intel x86 segment in the Android portfolio.
A 6
android for X86
s most would believe – Android is a mobile operating system that is open source and free for anyone to use, modify, develop and distribute. Nonetheless, there are some who rather prefer calling it an application stack where components are easily switchable suitable and exciting alternatives, thereby increasing variety. The only restriction you could think of would be modification of the core platform (such as not bundling the Play Store, Gmail or Calendar). Including these requires a licence and ensure that you comply with Android specifications while marketing your application. While this has made it difficult for manufacturers to differentiate their products in the market, it has enabled Google to keep the concerns of fragmentation at a minimum and made it easier to consolidate the Android market. This has however never stopped hardware manufacturers from selling products after putting on custom skins (Sense UI by HTC) and enabling proprietary device specific features (Multiwindow and the floating video player by Samsung) on their respective devices.
Open Handset Alliance Android is led by an entity known as the Open Handset Alliance, the organisation that made such an open platform possible. Though it is led by Google, there are a total of 84 members (as of today) who have made some major
android for X86
7
contributions towards the development of the Android platform. Of these, 34 of the member companies are founding members which include Mobile operators such as NTT DoCoMo, and T-Mobile; semiconductor companies such as Intel, Nvidia, Qualcomm and Synaptics; handset manufacturers such as Samsung, HTC, Sony, LG and Motorola; and software companies such as eBay and Nuance Communications. Since then, most major companies related to electronics, communications and software have joined the effort of making Android better day by day. These are those companies that not only support the ecosystem by bringing in devices that run Android, but also invest a significant amount of money and resources into it. These members who produce Android devices have to sign a contract that they will always support the community by not selling incompatible versions of Android. This not only results in much faster development of the platform, but an eventual merging of most of the features into the mainline, that a particular manufacturer develops. This reduces effort and develops trust among the competing manufacturers in the market, which are also benefits the community which has grown with a huge number of modders and hackers who continue to make their own innovations on the software.
Developer concerns From a developer's perspective, however, this shouldn't cause many problems because Android apps are promised to run similarly from the ground up, as long as you take into consideration the varying screen sizes and resolutions. This might be an advantage for many, but it is also the reason why many developers choose iOS first over Android, though that gap is narrowing day by day. The very fact that iOS is restricted to one mobile handset and tablet which is equally popular makes development and testing very easy, due to which developers and designers are able to offer a much better overall finish and user experience to their apps. Another reason might be the perception that iOS users are more likely to actually make a purchase and invest in an app than their Android counterparts who often use cheaper handsets which are often outdated and are not even available in the market. The main problem with such devices firstly is that they are not even available for testing by the developer and moreover they run much older versions of Android because the carrier or device manufacturer haven't released an update to the latest Android version. Most popular developers have often stated that they have to test the app for hundreds of handsets
8
android for X86
before actually releasing it in the app store. Keeping aside the downsides though, Android app development is actually much easier and offers much more flexibility. Android apps are allowed to change almost any component of even the base system, ranging right from the launcher to even the messaging and music application. This is the kind of customisability that iOS will never be able to provide. What's more apps are able to share data among themselves much more easily using intents, which is a great way to touch the boundaries of freedom. Android development also runs at a much faster pace than its competitor, so most of the quirks or irritations that you might have usually tend to get addressed in the next release or so. This might also mean that you have to make sure your app works for users right from Android 2.3 Gingerbread to JellyBean 4.1/4.2.
A brief history Android has grown a lot through the past few years, when it first came out in November 2007 as a beta, it already had an SDK to go with it. The first official release was however only a year later in September 2008 with features such as the Android Market (now known as the Play Store), camera, Wi-Fi, Bluetooth and sync support in addition to instant messaging. The first major release that turned out to be quite popular with its dessert name was Android 1.5 “Cupcake�. This release brought along with it some major features and refinements like screen rotation, on screen keyboard with text prediction, app widgets, Bluetooth audio streaming with A2DP and a newer
android for X86
9
Linux kernel 2.6.27. Eventually development sped up with release of more candies like Donut, Eclair and Froyo. Each of which brought about a slew of features like a new Text to Speech Engine, a new search framework along with gestures and accessibility support for Donut. Android 2.0 Eclair, as expected turned out to be a big release from a user's perspective, which also introduced the much popular WebView support for developers. But the next release i.e. Froyo, turned out to be a bounty for developers which featured cloud to device messaging for two way push notifications, crash/ bug reporting and allowed apps to be installed on the external SD card. The most popular platform till date however, which still holds a sizeable portion in the amount of active Android devices has been Gingerbread or Platform version
API level
Version Code
Android 4.2
17
JELLY_BEAN_MR1
Android 4.1, 4.1.1
16
JELLY_BEAN
Android 4.0.3, 4.0.4
15
ICE_CREAM_SANDWICH_MR1
Android 4.0, 4.0.1, 4.0.2
14
ICE_CREAM_SANDWICH
Android 3.2
13
HONEYCOMB_MR2
Android 3.1.x
12
HONEYCOMB_MR1
Android 3.0.x
11
HONEYCOMB
Android 2.3.4 Android 2.3.3
10
GINGERBREAD_MR1
Android 2.3.2 Android 2.3.1 Android 2.3
9
GINGERBREAD
Android 2.2.x
8
FROYO
Android 2.1.x
7
ECLAIR MR1
Android 2.0.1
6
ECLAIR_0_1
Android 2.0
5
ECLAIR
Android 1.6
4
DONUT
Android 1.5
3
CUPCAKE
Android 1.1
2
BASE 1_1 (Internally known as “Petit Four”)
Android 1.0
1
BASE
10 android for X86 Android 2.3. This release added some major features like NFC, Gyroscope and SIP protocol support. It also added several improvements to the UI and available controls. Later came Honeycomb with major focus for tablets and a UI overhaul which was to be integrated in Ice Cream Sandwich later. ICS came with support for Android Beam, unified social API, VPN client API, Text to Speech API and most importantly unified framework for phones and tablets. Jelly Bean, the most recent revision has added features for developers like USB Audio output, app encryption, app verification, script intrinsics and filterscript support. The API levels mentioned in the table represent a unique integer value that specifies the corresponding revision of the framework API. It is used to identify the minimum, maximum and target API level at which the application can work. Hence, it is used to manage the compatibility requirements of various Android apps, who need to specify their API requirements in their manifest. The version code on the other hand have always represented the official name by which newer Android versions are known as. These have been named alphabetically after desserts ever since the Android 1.5 version which was called “Cupcake�. There have been no official names starting with A and B, though there have been rumours that these had some internal references within the company.
Android Architecture Nothing beats the way architecture has been explained in the official docs, still the overall software stack consists of overall five components that make the whole platform work. These are a set of loose software layers that work with each other like any other computer operating system, just that they are heavily optimised specifically for mobile environments. The fact that it is based on the Linux kernel results in the fact that it is even more robust, community tested and portable to run on almost any other device. The dalvik virtual machine provides a layer of abstraction, just like a Java VM, so that apps are able to run without worrying about the underlying platform of the mobile or tablet device. This is precisely the reason why Android has been easily ported to unconventional devices like watches, refrigerators and in-car entertainment systems.
Kernel As, we discussed before, Android is based entirely on the Linux kernel
android for X86 11
which directly interfaces with the mobile hardware to handle drivers for each functionality and handles memory, power, network and process management. This is the layer on which the Dalvik Virtual Machine and core libraries run. The kernel being open source has prompted a number of hobbyist hackers and modders to release their own popular versions of kernels for specific devices. It has often been an important topic of discussion for people who want to tweak their CPU governors, I/O schedulers and custom kernel modules. This has given rise to an interesting community that customises their
12 android for X86 devices to suit their preferences. There have been instances when Android has been ported to run even on phones that do not officially bundle it.
Dalvik Dalvik is the most important component that runs Android applications. It resembles the Java Virtual Machine in the sense that code written in Java is converted to bytecode and then into a Dalvik executable (.dex) which is
done with the dx tool. This particular format has been used because it is very beneficial for memory and power limited devices and runs without any swap space available, as opposed to Java which has considerably higher requirements.
Libraries Libraries are exactly what they sound like – low level software bundles that handle basic device functions such as 3D hardware acceleration with
android for X86 13
OpenGL, Surface Manager as the display subsystem to handle multiple layers of software applications. This layer includes an implementation of the standard C system library (libc). The SQLite database used for storing information is also an important component that is used extensively.
Applications Applications are the components that app developers like you or me develop. These can be system apps like SMS messaging, E-Mail, Home Launcher, Contacts, Dialer, Settings etc. Basically, anything that is presented in front of you is part of app that has a specific lifecycle.
App Frameworks App frameworks are a set of services that expose an API and provide access to device functions like displaying views, accessing data, pushing notifications to the main notification bar, application lifecycle management etc.
Chapter 2 14 Getting Started
Getting Started while The Android SDK allows you to get started with app development, when paired with an IDE and API libraries, platform tools, ADT plugin and the Android system image it gives you a complete environment to ease and supplement the process of development, testing and debugging your application.
Getting Started 15
Basic Prerequisites The basic system requirements listed by the Android developer website are as follows: ΩΩ Windows XP (32-bit), Vista (32- or 64-bit), or Windows 7 (32- or 64-bit) ΩΩ Mac OS X 10.5.8 or later (x86 only) ΩΩ Linux • GNU C Library (glibc) 2.7 minimum. • Ubuntu version 8.04 or later. • 64-bit distributions should run 32-bit applications. The SDK and other tools procured from the official website have been tested for Linux only on the Ubuntu distribution. Though other distros might have their own packages in their official repositories which are community tested. We would recommend using those instead, because setting up and updating them would be much more easier and streamlined. Other than these platform requirements, Android SDK requires JDK 6 (Java Development Kit) to be installed on your operating system. It should be stressed specifically that Gnu compiler for Java (GCJ) is not supported and older versions of the JDK are also incompatible. By default, the IDE that is supported by the Android SDK is Eclipse ( At least Eclipse Helios 3.6.2), which is actually even bundled with the ADT bundle for your specific platform.
Getting the SDK The SDK can be procured from the official website and is available as part of an ADT bundle or as a separate SDK Tools bundle if you have a development environment already set up. As mentioned before, the ADT tools bundle already includes everything you need in order to get started with running a new development environment for Android including the Eclipse IDE. The package is available for all the three platforms including Linux, Windows and Java. It can be downloaded from the Android SDK download page (dvwx.in/VKWyKI), which will show you a “Download the ADT Bundle for Linux/Windows/Mac” button on the right as per your present platform. If you want to download it for a platform which is not your current one, you can click the “Download for other platforms” link at the bottom and it will show you the list of platforms which are supported for the ADT Bundle as well as SDK Tools. If you feel that you need just the SDK and have to integrate it with some
16 Getting Started existing IDE, you can click the “Use Existing IDE” link, which will show you the “Download SDK Tools for Linux/Windows/Mac” button.
Setting up with the ADT bundle To install and set up the ADT bundle, all we need to do it is to have a Java JDK already installed on our system and launch the eclipse IDE after extracting the zip file that comes in the download. So, basically what we do is the following: 1. Make sure that JDK and not just JRE is installed on your system. 2. Unzip the ADT bundle archive that came after being downloaded from the Android developer website and place it where you would want your Eclipse and Android SDK directories to reside. Make sure you do not change the folder structure, because changing it will result in you having to change the Android SDK preferences in the ADT plugin for eclipse. 3. Add the full path to the sdk/platform-tools and sdk/tools subdirectory to your PATH variable so that you can access the relevant commands from anywhere, otherwise you will need to type in the full path to each command everytime you run it. Finally, all you need to do is to launch the eclipse environment and choose a default workspace where all your development related files will be stored.
On existing Eclipse environment Windows The Windows Android SDK installer comes as an executable which exposes a wizard like interface which checks for dependencies and allows you to choose a location to install your SDK. Since these are only the SDK tools, it will only install the bare minimum packages required to start development. You will still need to configure this from eclipse and download more packages like the Android Platform Tools and the Android System Image which will
Getting Started 17 be used for the emulator. You might also need to add the path of the sdk/ platform-tools and sdk/tools subdirectories to your PATH variable in order to use common Android SDK utilities. Mac / Linux The Mac and Linux SDK comes as a zip file which can be extracted and put anywhere you intend to keep it. Finally, as in windows – add the sdk/ platform-tools and sdk/tools subdirectories to your PATH variable with the following methods: Linux Edit the ~/.bash_profile or ~/.bashrc files looking for a line that sets the PATH variable. 1. Add the full path location to your $SDK_ROOT/tools location for the PATH variable. 2. If no PATH line exists you can add the line by typing the following: 3. export PATH=${PATH}:<path to your $SDK_ROOT/tools> Mac In the home directory locate the .bash_profile and locating the PATH variable add the location to your $SDK_ROOT/tools folder.
Setting up the Eclipse IDE Now that everything is set up and the development environment is good to go, all that we have left is to procure the Eclipse plugin and install additional packages that include the target platform and other APIs after integrating it with the exisiting IDE on your system. If you still want to install the IDE by yourself, you can do so by getting the Eclipse for Mobile developers package at the eclipse.org/mobile/ website which is again available for all the three popular platforms. To install the Eclipse ADT plugin, we need to add the Google repositories in its Add-On installation dialog. This can be done as follows:1. Start Eclipse and navigate to Help > Install new Software. 2. Click the Add button and name the repository as something like “Android ADT”. The online location for the repository is : https://dl-ssl.google.com/android/eclipse/ 3. It will list a couple of available sites, from which you can choose
18 Getting Started “Developer tools” and check the components you would like to be installed in the next screen. 4. Finally, accept the license agreements and restart eclipse when the installation and download is complete. 5. When eclipse restart is complete, you will need to set the location where you installed your Android SDK. You can do this directly in the “Welcome to Android” window or go to Window > Preferences and choose Android on the left, which should show you a field to specify the Android SDK location. This concludes the configuration of the eclipse development environment, following which only additional packages like target platforms and APIs are left to be installed.
Target platforms and APIs As a last step towards environment setup, you must install at least one android platform for which you are aiming to target you app. It will be used to set up the emulator on which the system image will be used to run your application. The ADT bundles the lastest available android platform by default. If you neeed a slightly older version for which you are targeting your app, like Android 4.0.4 or Android 4.1 or you had downloaded the SDK Tools instead of the bundle, then you will have to download it from the Android SDK Manager. To launch Android SDK Manager on Linux or Mac, use the “android sdk” command to launch the Android SDK Manager dialog. On Windows, you can launch it after locating the SDK Manager.exe file from the SDK directory. Alternatively, it can also be launched from the Eclipse IDE itself, by clicking the corresponding Android SDK Manager button below the menu bar. When you launch the SDK Manager, it should start downloading the list of available packages from the server and then show you a list of those which are already installed along with the ones which are available. At the minimum, make sure you have at least all the Tools packages, one Android platform (like Android 4.2) and the Android Support Library installed, to be able to work sufficiently in your development environment.
x86 system Image Targeting your apps for x86 Platform is very easy. You need to select and install Android x86 System Image in Android SDK Manager and within couple of minutes, your Android x86 System image is up and ready to build apps!
Getting Started 19
Third party addons Besides the default addon packages for Android SDK available from Google, a number of third party websites might host customized add ons for their own specific devices. These can be carriers, manufacturers or software development companies as well. To enable the third party addons you need to find a link to the repository.xml file for that particular repository, and add them to the SDK Manager. To do this, click on the Tools > Manage Add-On Sites. This will show you the Add-On Sites dialog box, where you can find the User defined sites tab. Click on New and add the link to your specific repository file. To refresh the list of available packages, click on Packages > Reload.
Creating a new Android Virtual Device An Android Virtual Device stores the configuration for the emulator according to which it will do the emulation for your application. By default Google provides emulation profiles for all the old and new Google Nexus devices. Manual configuration can also be done for other devices. Android Virtual Devices or AVDs can be created from the AVD manager, which provides a decent GUI for configuring and editing the devices. The AVD manager can be launched from the Android SDK manager too, by clicking on Tools > Manage AVDs. In the AVD Manager screen, click on
20 Getting Started
New, which will show a Create new AVD dialog box with various configurations. It will allow you to name your device and specify the target. For example, if you intend to develop for Intel based devices, you would choose “Intel Atom x86 System Image” that you should have installed before. It will further ask you for device configurations like size of the SD Card, screen size, DPI, RAM size etc. After all this configuration, click on Create AVD and you device should be listed on the main screen. You should now be able to launch the emulator by clicking on the “Start” button after selecting the device you want to launch.
Using the Android System Emulator The emulator can be controlled easily from the on screen buttons or with the help of keyboard shortcuts. There are also various commandline options to turn on or off specific set of functionality. The keyboard shortcuts are quite important and are listed in the table, as referenced from the official documentation.
Getting Started 21 Emulated Device Key
Keyboard Key
Home
HOME
Menu (left softkey)
F2 or Page-up button
Star (right softkey)
Shift-F2 or Page Down
Back
ESC
Call/dial button
F3
Hangup/end call button
F4
Search
F5
Power button
F7
Audio volume up button
KEYPAD_PLUS, Ctrl-F5
Audio volume down button
KEYPAD_MINUS, Ctrl-F6
Camera button
Ctrl-KEYPAD_5, Ctrl-F3
Switch to previous layout orientation (for example, portrait, landscape)
KEYPAD_7, Ctrl-F11
Switch to next layout orientation (for example, portrait, landscape)
KEYPAD_9, Ctrl-F12
Toggle cell networking on/off
F8
Toggle code profiling
F9
Toggle fullscreen mode
Alt-Enter
Toggle trackball mode
F6
Enter trackball mode temporarily (while key is pressed)
Delete
DPad left/up/right/down
KEYPAD_4/8/6/2
DPad center click
KEYPAD_5
Onion alpha increase/decrease
KEYPAD_MULTIPLY(*) / KEYPAD_DIVIDE(/)
Android SDK with IntelliJ Idea Setting up Android SDK with Android SDK does not require much configuration after the SDK has been configured as before. The only difference is that you need to download the SDK Tools package and manually configure it instead on downloading the SDK bundle. Since, IntelliJ Idea supports Android app development by default, you don't need to download or install anything to enable support, only a little bit of configuration is required. The
22 Getting Started main prerequisite is that you need to have the Java JDK and Android SDK configured. Android support in IntelliJ Idea is provided with the Android Support plugin that is bundled by default. If however you find that it is not available, you can enable it in the plugins configuration wizard or the plugins tab in the settings dialog box. The only remaining configuration that remains regarding the Android SDK and Java JDK can be done by adding a new Android project or adding an Android facet to an existing project. When you do so, the respective wizards will automatically ask you to specify the location of the Android SDK and Java JDK.
Android SDK with NetBeans The process for configuring Android SDK is also similar with NetBeans. Again, the Android SDK and Java JDK obviously need to be set up and configured first. The Android app development functionality is provided in NetBeans with the help of the nbandroid plugin for Netbeans. To install this plugin, following steps need to done :1. Go to Tools > Plugins. Add the update center link for nbandroid to the list in the Settings tab : http://kenai.com/projects/nbandroid/downloads/ download/updatecenter/updates.xml 2. Now in the Available Plugins tab, install the Android plugin that should now be available. 3. To configure the path of Android SDK, go to Tools > Options > Miscellaneous > Android. 4. Mention the location of the Android SDK in the available field. You should now be able to easily create new Android projects and applications. Optionally you can also install the plugin manually by installing it from a downloadable zip file. This can be done as follows :1. Download the plugin from the nbandroid website : http://kenai.com/ projects/nbandroid/downloads 2. Unzip the file and go to Tools > Plugins > Downloaded 3. C lick on Add plugins and select those which match the vsersion of your current IDE. 4. C lick on the Install button, which will ask you to accept the licenses after which installation will begin. It should be noted that Android development with other IDEs is rec-
Getting Started 23 ommended only when you are accustomed to their interface or already use them on your system. If you are a new Android developer, the official eclipse plugins are more than enough and will get better community support if you face any problems with the plugin or during the process of your development.
Android SDK in Other Linux Distributions To give you an example of setting up a development environment in other Linux Distributions, it is sometimes much easier to get the SDK from the official repositories which provide it in the form of a preconfigured package.
Arch Linux Arch Linux, for example provides two AUR (Arch User Repository) packages by the name of android-sdk and android-sdk-platform-tools. The process for installing these AUR packages is as usual and these provide access to the Android SDK quite easily. If you want to use eclipse as you development environment, a package called eclipse-android is also available.
Intel Hardware Accelerated Execution Manager Intel Hardware Accelerated Execution Manager is a hypervisor (or a Virtual Machine Manager) that greatly speeds up the execution of the commands in the emulator. Intel claims that it does this by almost 5 to 10 times the performance of an emulator without the presence of HAXM. The surprising fact is that it is actually true and apps are noticebly much faster and even NDK based games and resnderscript based heavy computations are supported which suddenly become much more smoother to run and thankfully no longer require a real development device to be bought for testing and development purposes. The result is that it not only saves time, but also a lot of money. HAXM works on Intel-VT enabled processors and is supported on all the three platforms namely Windows, Mac OS X and Linux as long as they are on Intel processors and use the Intel Atom X86 System Image. It uses the hardware virtualization features built into the Intel processors, as opposed to much slower software based emulation, where most of the virtualization is done at the hardware level on the host processor. It even supports GPU emulation (since SDK release 17), so that OpenGL calls can be executed on the host. Imagine the amount of graphics performance that
24 Getting Started is enhanced by this very functionality, where only the peripheral emulation is left to be handled by the software. The installation of Hardware Accelerated Execution Manager requires the following minimum system requirements: Intel processor with VT support • 1 GB RAM • (Mac OX 10.6 Snow Leopard / 10.7 Lion) / (Microsoft Windows 7, Vista, XP SP2 32 bit) / (Ubuntu Linux 64 bit recommended) • Android SDK • Android X86 System Image • JDK All the above system requirements are checked by the HAXM installer, which if not met, makes the installation to be failed. To check if your processor is supported or includes the VT technology, you can check the system BIOS or refer to the Intel website. To install HAXM, it can be procured directly from the Intel website or from within the Android SDK Manager itself from under the Available packages below extras folder. Getting Intel HAXM from the Android SDK 1. Start the Android SDK manager with the android sdk command. 2. Go to Extras and check the Intel x86 Emulator Accelerator (HAXM) entry. 3. Click the Install button. 4. Review License Agreement and Accept it, followed by which you need to click Install Again. 5. The Installer will be downloaded to the tools directory under the Android SDK folder from where it can be run to continue the installation. Installation of Intel HAXM on Windows 1. Run the Installer that you downloaded from the Intel Website or from the Android SDK Manager. 2. Accept the License Agreement and Click Next. 3. The Installation Wizard will ask you to allocate the amount of RAM you want to use for HAXM. By default this setting is 1024, if you want to use more than 2048, it is recommended that you only use a 64 bit system. 4. When the Installation is finished, go to command prompt and check if
Getting Started 25
From the Android package manager, install Intel Hardware Accelerated Execution Manager
it is running by typing the command sc query intelhaxm. This should show you a status as Running, if not then try starting it and if you face any errors, try reinstalling the whole software. 5. Additionally you may see some errors regarding Intel XD or Intel VT-x not being enabled, in which case, you will need to go into the BIOS and enable this setting. If the installer says that either of these settings is not supported by your processor, then you will not be able to use this software. Installation of Intel HAXM on Mac OS X Installation of Intel HAXM on Mac OS X is similar to Windows with the help of the Installation wizard where you will need to specify the amount of memory to be allocated. To check if HAXM is running, you can run the kextstat | grep intel command which should show you the kernel extension named com.intel.kext.intelhaxm to be loaded in memory. Installation of Intel HAXM on Ubuntu Ubuntu Linux is one of the main platforms on which a lot of developers use Eclipse and AVD to work on building their Android applications. A
26 Getting Started lot of build servers are also based on Linux and hence it is very important for Intel to support Hardware Assisted KVM Virtualization in a manner similar to HAXM on Windows and Mac. The following KVM installation instructions can also be referred from the Ubuntu Community documentation page for KVM.
Installing KVM
•
1. The first task is to check for prerequisites and see if the required configurations are indeed suppoted on your system. So, to check if your processor supports hardware virtualization, run the following command : egrep -c '(vmx|svm)' /proc/cpuinfo
If the output value turns out to be zero then your processor does not support hardware virtualization and if it somehow turns out to be greater than that, you are good to go! 2. To check if KVM is suppported on our system, we need to install the CPU checker utility, with the help of the following command: sudo apt-get install cpu-checker When this is done, you will be able run the kvm-ok command to see if KVM is supported. 3. F inally, if you want to allocate more than 2GB RAM to a VM, then it is required that you have a 64 bit system. To check for that, run the following commands: • egrep -c ' lm ' /proc/cpuinfo
If the output is 1, then it means that you are running a 64 bit system. In order to make sure that you are also running the 64 bit kernel currently, you can run uname -m command to check for the architecture. 4. To get started with the installation, the required packages can be installed from the repository as follows: • sudo apt-get install qemu-kvm libvirt-bin ubuntuvm-builder bridge-utils
•
5. It will ask for postfix configuration during the install process, which you can ignore by choosing the No Configuration option. 6. To start using the KVM virtualization, you need to add the user that will be running the software to the kvm and libvirtd groups. 7. Log out and Log in again to make the changes effective. 8. To see if everything has been set up, check the output of sudo virsh -c qemu:///system list.
Getting Started 27 9. To start the emulator from the commandline, you can execute: emulator-x86 -avd Your _ AVD _ Name -qemu -m 2047 -enable-kvm
â&#x20AC;˘
10. Alternatively, to use it from eclipse you will have to change the Run Configurations for the Android Application Project. There you will have to choose the x86 based AVD that needs to be run as the target and in Additional commandline options, you will have to specify the following: -qemu -m 2047 -enable-kvm
Chapter 3 28
Developing for Android Given the rise of Android in the Indian market, and the variety of mobile devices, an app's availability on the Google Play Store gives it immense visibility. With this advantage comes another challenge--that of customisation.
Developing for Android 29
The Android building blocks After installing the sdk, the first major task is to understand the basic building blocks that make Android up. Once we've gotten familiar with the basic building blocks of Android we will write a simple Android application to illustrate how to use them in a rather practical setup. The basic Android building blocks are: • Activities • Intents • Views • Content providers • Services • Notifications • Android manifest Before we proceed to building an app, let's go through each building block and understand what role they play in the life of an Android application.
Activity An activity is a core building block and is at the heart of most Android applications out there. To put it simply, an activity is what you see on a screen in Android. Users can interact with this screen to accomplish a particular task. As an example, consider the dialer screen as an Activity. Whenever a user wants to dial a number and make a call, he/ she must use the dialer 'Activity' or screen to enter the number. While the user inputs the digits to be dialled, each activity is given a window in which to draw its user interface and a developer can specify how he/she wants the activity to look. As you might guess, an Android application might have multiple screens and therefore might contain multiple activities. For example, a dialer application
30 Developing for Android might have an Activity where you enter the number to be dialed, once you hit 'dial' it might invoke another Activity that shows the number which is being dialed and so on. So, applications typically have multiple Activities in Android and the activity which is presented to the user when launching the application for the first time is called the 'Main' Activity. An Activity also has a lifecycle of its own and at some point in the same lifecycle the Activity is created, started, paused, stopped and eventually destroyed. In other words, when the screen is shown on the screen - in developer terminology, it comes to the foreground - the Activity is 'created' and then 'started'. So any basic setup for the activity is done in the onCreate method, which is called when the Activity is getting created before being shown on the screen, typically, you would be setting up the User
Source: android.google.com http://dvwx.in/Y0mCh9
Interface of the Activity here. Similarly, there are similar methods/callbacks like onStart, onResume, onPause, onStop and onDestroy which are called when the Activity is being started, resumed, paused, stopped or destroyed respectively. A quick note here, an activity which is in the foreground (directly
Developing for Android 31 visible on the phone) is said to be in an 'Active' state and is able to perform operations, as soon as the user starts another Activity, the old Activity is 'paused' and stopped and then 'pushed' on a stack called the 'Activity stack'. In this state, the activity is no longer able to perform any operations. If the user goes back from the new Activity to the old Activity, the old Activity is then 'popped' from the Activity stack and then 'started' and 'resumed' to go back to normal operation.
Intent As mentioned previously, there might be multiple Activities in an Android application and we might need to move between them. An Intent is a mechanism by which we can move between Activities or between other Android building blocks such as Services. More on that later. Let's take the example of the dialer application again, when you are in the Android home screen, you are basically in the home screen Activity, here when you click the dialer button, you use an 'Intent' to launch the dialer application 'Activity'. There you enter the phone number that you want to dial and hit the dial button which uses another 'Intent' to launch the dialing 'Activity'. You can also pass data in an Intent, for example, when you enter the phone number of a person in the dialer and hit dial, you might want to pass the phone number as a parameter to the next Activity and you can pass that using the Intent itself.
Views Views are the basic User Interface building blocks in Android and an Activity is typically made of many such atomic 'Views'. Simply put these 'Views' know how to draw themselves on the screen and they respond to user events like a click or a long press. Example of Views in Android are TextViews which show simple text on the screen, ImageViews which draw images on the screen, EditText which let users enter text and so on. Views are also hierarchically arranged in the form of trees to draw fairly complex user interface layouts. For example, here in the twitter app, 4 ImageViews (the Twitter logo, the refresh button, the tweet button and the search button) are arranged linearly to form one atomic element called the 'ViewGroup'. Since we arranged all the elements linearly (in a straight line) we call it a LinearLayout ViewGroup.
32 Developing for Android
Similarly if you look a tweet row in the twitter app, the various TextViews and ImageViews are arranged in a row to form another ViewGroup. The idea is that we can arrange all these individual Views together in a way that makes sense to the user and all Android applications group views together to make very complex layouts like the one shown in the twitter app. Also note that the layout which specifies the arrangement of the
Developing for Android 33 individual views is typically mentioned in a separate xml file. Defining the layout in an xml file enables Android to conform to the Model View Controller architecture pattern and helps separate the User Interface component from the actual code.
Content Providers As you might know databases are used to store and retrieve information and Android provides an inbuilt database called SQLite to achieve that functionality. It also provides an additional functionality called 'Content Provider' to enhance the functionality of a database in a mobile scenario.
So a Content Provider is a wrapper on a database that provides additional functionality to share data with multiple applications and to manage data security with respect to the same. Let me illustrate that with an example. Let us say there is a contact application that does contact management on an Android phone. As discussed before, that application might have multiple Activities within it, like an Activity to add a contact, another Activity to view all the contacts, another one to Edit a contact and so on. When you add a contact, instead of directly asking the database to add a row for the contact, you would ask the 'Content Provider' to add that row for you. The Content Provider would then have the logic of knowing where to store the row, in the database, in a file or even in the cloud. Now say there is another application, say an sms/text app which
34 Developing for Android needs access to a persons phone number. Now under normal circumstances, getting access to that data would be a cumbersome job (sharing a database is not always straightforward) but thanks to the ContentProvider which makes data sharing easy, we can do that in a flash. So when the sms app needs access to the phone number, it queries the contacts 'ContentProvider' which in turn knows where the data is stored and where it should look. Once the query is complete, it then returns the results back to the sms application. This provides a very simple and straightforward approach to sharing data between multiple applications while maintaining security.
How it all comes together...
Services You might recall that while discussing Activities, we saw how Activities are 'paused' and 'stopped' when they go into the background. You might think that this might be a problem for applications that need to keep working in the background for a long time, like a music player or a download application. Apps like that might have a tough time performing while in the background and need a way to keep playing music or continue downloading even when they are not in the foreground. For such functionality, a 'Service' should be used. In other words, a Service is a faceless task that runs in the background and has no user
Developing for Android 35 interface. You can enable it to run for a specific amount of time and do a certain task. Any task which should be done even if the corresponding Activity might be pushed to the background should be delegated to a Service. Now that you are slowly understanding the basic building blocks of Android, you are starting to get a picture of how Android applications are built, they are often a combination of all such blocks, like an app typically has multiple Activities, many Views, maybe a ContentProvider and maybe even a Service, all depending on the use case
Notifications Notifications are one of the hallmark features of Android. They notify users about events and provide visual, audio or vibration feedback. In the newer versions of Android, you can even empower users to provide action on the notification. For example, in this recording application, while playing back a recording, you can enable users to pause the playback or skip to the next track from within the notification itself.
Android manifest The final basic building block of Android is the Android manifest file. This file provides critical metadata about your application, like the package name for your app, the various components like Activities, Services etc. in your app, the permissions that your app might seek (example: your app needs to seek the 'INTERNET' permission to be able to access the internet), the libraries that your app uses, the version of Android you support and so on. It is a very important building block as the appearance and functionality of the whole application depends on the declarations you make in the manifest file.
A simple application Now that we've gone through the basic building blocks of Android, we'll see how we can harness the same building blocks to create a simple music player program in Android. The application is intended to be really simple and will provide functionality to play, pause and stop a predefined music file. Again, to keep things simple, the UI is expected to look something like this:
36 Developing for Android To create a new program, go to File>New>Android Application Project In that screen, enter the name of the application say Simple Music Player As you might have noticed, as you enter the name of the application, the project and package name for the app start populating automatically. The package name is typically in the format of com.<Your Organisation name>.<Your application name> There are some other variables that are filled by default, like the minimum required sdk, target sdk etc. which let us specify the version of Android we are targeting but let us not look at them right now, just click next.Hit next on the next screen. On the next screen, you can select the launcher icon for your application, you can play around with the Example of a content provider app launcher icon for your application, for now, just leave everything at its default value and hit next. The next screen in the wizard highlights what kind of 'Activity' is created in your application by default. Since we are making a simple application, just hit Next. The final screen is about the name of the Activity created by default and the name of the file that specifies the layout (remember the separate xml file we discussed before), for now, lets again leave everything to their default values and hit Finish. Once you hit finish, you are taken to the UI editor which previews how your application looks by default. As you can see, the default application has a View which shows 'Hello World' in the centre of the app, this is the UI visual editor in Android. Now let's get started with the User Interface design of the application, to begin, click on the 'hello world' TextView at the centre of the screen and hit Delete. Next, as we need three buttons in the application, let us drag and drop three buttons from the "Form Widgets" section of the Palette on the
Developing for Android 37 left to the top left of the Android screen like so: Drag all the three buttons in a straight line so that it appears as seen the image below: Next click on 'activity_main. xml' at the bottom to view the underlying xml code that generates this layout. It is very important to know how these layouts are generated as understand them will help you design even more complex layouts. Here you can see that there is a 'RelativeLayout' element at the very start which contains 3 'Button' elements inside it. We shall cover the RelativeLayout ViewGroup in a later chapter, but A sample music player app here it is important to understand that the RelativeLayout ViewGroup specifies how the child elements (each button) is arranged on the screen. Note that each child/button has a number of different attributes, the first of which is an id, followed by others. Let us quickly describe some of them. The android:id attribute identifies the element in the xml file and can be used to reference the same from within the code, for example, the id for the first button is '@+id/button1' which translates to the following: the first button should create a new id with an id of 'button1'. So in code, whenever we need to reference this button, say we want to know when it was clicked, we will need to use the id of 'button1'. Buttons in the app The android:layout_width and
38 Developing for Android
To begin your Android project, go to File > New
Enter the name of your application
android:layout_height attributes highlight the width and height of the element respectively. Here we say that the width and height of the button should be 'wrapped' to the width and height of the content in the element, in other words, in case the text in the button should increase, the length of the button would increase automatically. The android:text attribute highlights the label of the button, let us
Developing for Android 39
After you enter your application name, you need to configure its icons
change that to Play, Pause and Stop for each of the buttons and hit Save (Control + S/Command + S). Hit the Graphical Layout tab and see how the labels of the buttons have changed to reflect the changes in the android:text attribute.
In the next step, you'll have to select the type of activity
40 Developing for Android
The last wizard screen
Folder structure Now that we've started working on the look of the application, the next step is to get familiar with the rest of the application. Notice the package explorer section to the left of the eclipse window, that window displays
Once you're done, you'll see the layout of your app as it stands
Developing for Android 41
Drag and drop buttons as you need
a list of the folders that make up your application. Let us go through those folders one by one. The first folder on the left is called 'src', as the name suggest, it contains the source code of your application. Program code such as
Three buttons in a line (outline 'activity_main.xml' in a circle)
42 Developing for Android
Acitivity_main.xml
Set the text within activity_main
MainActivity.java resides in this folder. As you can see, individual java source files are arranged under their respective package names. Double clicking on a file (like MainActivity.java) will open it in the central edit area of Eclipse, it is there that you will be spending most of your time. Lets take a quick detour here and check out a folder called 'res'. This
Developing for Android 43 folder represents the list of resources used in your application. Resources can be of many types, images/vectors or 'drawables' as they are called in Android are one type, layouts like the one that was created by default is of another type, Android menu's (the things that pop up when you press the menu/settings button your phone) are of another type. Even layout styles and external strings are considered resources in Android and can be stored under their respective folder in this directory. Note how there are multiple folders which begin with 'drawable' here called drawable-hdpi, drawable-ldpi, drawableThe folder structure mdpi and drawable-xhdpi. DPI in HDPI stands for dots per inch and the H, M, L and XH stand for High, Medium, Low and Extra High respectively and they represent the screen densities of devices that users might have. A galaxy nexus which has more than 300 dots per inch falls under the xhdpi category whereas the nexus s which has a lower pixel density falls under the hdpi category. The idea here is to store different resolutions of the same image in different folders so that Android can automatically select which is the best image for the users phone at run time. So for example, you might store a very high resolution image in the xhdpi folder and store a lower resolution version of the same in hdpi and then a lower one in mdpi and so on. Note that in addition to pixel density you can attach many other such qualifiers to the folder name to specify how Android chooses resources at run time. For example you can choose a specific resource if the phone is in portrait mode and another when you are in landscape mode. More of that is available in this link: http://developer.android.com/guide/practices/ screens_support.html Moving on, the next folder is called 'gen', this folder contains files that are automatically generated by Android and should never be tampered with. The file R.java is of particular importance, basically whenever you add a resource like a new layout, a View etc. in an app, Android automatically catalogues it for you in this file. This is done so that
44 Developing for Android you can easily refer to it in your program without any manual intervention. See how different drawables, layouts, menus, strings and all other resources are given an identifier here under all the different classes. Our activity_main.xml file here is represented by the int activity_main in the class layout, which translates to R.layout.acitivity_main So say you create a new layout called newlayout.xml in your application, thanks to this automatic catalogue, you would then be able to refer to it as R.layout.newlayout Next we see some of the libraries that are used in the application. We can see the Android 4.2 and some other Android dependencies that is used to compile the app. The next folder is the assets folder where you can store raw assets. Next we have the bin folder which is the output directory of the build of the Android app. Here you would find the final apk file for your application after a build is complete. Finally we have the libs folder, where you can store private or 3rd party libraries.
Developing for Android 45 There are also other files like AndroidManifest.xml which we have discussed before. Now that we have understood the basic directory structure of an Android apps, let us get back to our app. Remember that we have designed the basic look of our application, the next step is to go into code and find out when a button has been clicked. To do that, first click on the MainActivity.java file under your respective package name. This file represents the 'main' or first activity of your application and this is the activity that is launched when your app is launched. Also note that there are some pre-created methods for you. The first one is onCreate and that is what we're really interested in. As discussed before, an Android activity has its own lifecycle, it is created, started, paused and so on. Along the same lines, when the activity is first created, the onCreate method is called and this is where you should do a lot of Activity initialisation jobs. Notice how there is a statement called setContentView(R.layout.activity_main) in this method, this tells Android that when the activity is created, set the view of the application to what is represented by R.layout.activity_main. In other words, whenever the application is started, the layout inside activity_main.xml will be shown on the screen. Our first task here is to find out when a button is clicked, more specifically, when the play, pause and stop buttons are clicked. So we need to get a reference to the buttons and then set listeners (remember Java listeners) on them. To create a reference to the play button we need to write the following statement â&#x20AC;˘ Button playButton = (Button) findViewById(R. id.button1); This statement basically tries to get a reference to the button by using the id of the button which is 'R.id.button1' on the method findViewById. The method findViewById returns a generic View object which we must typecast to 'Button' to get a proper button reference. Note how you might get an error in the form of a red underline under 'Button'. If you hover over button you will find that it states "Button cannot be resolved to a type" which basically means that it needs to import a package in order to understand what 'Button' is. If you hover over button, you will also find that Android has offered you with around 7 quick fixes, the first of which is to "Import Button (android.widget).
46 Developing for Android When you click that Android automatically imports the necessary package so that you don't have to manually do it. Do that and you will see that the errors have disappeared, there are still a couple of warnings but lets ignore them for now. Write a similar statement to get references to the other buttons like so: Button pauseButton = (Button) findViewById(R. id.button2); • Button stopButton = (Button) findViewById(R. id.button3); •
Once you do that, the next step is to attach 'onClickListeners' to these buttons so that they you are informed as soon as the buttons are clicked. To do that take the first button and then type the following •
playButton.setOnClickListener()
inside the brackets we need to create an anonymous inner class for the listener, to do that type new and then press control + enter to let autocomplete take over. Select the first option which is View.OnClickListener and hit enter. The code should look something like this: •
playButton.setOnClickListener(new OnClickListener() {
@Override • public void onClick(View v) { • // TODO Auto-generated method stub • • } • }); •
Remember to put a semi colon at the end and hover over the OnClickListener in new OnClickListener() to import the necessary package. Notice how all the errors have magically disappeared. The idea here is that as soon as the play button is clicked, the method onClick inside that new OnClickListener is called. Over there we can do our processing. For now we'll show a short message called 'Toast' here.
Developing for Android 47 Toast.makeText(MainActivity.this, "Starting to play", Toast.LENGTH_SHORT).show();
•
This line will enable us to show a short message: "Starting to play" on the screen. Now let us try this on the emulator, run this program by right clicking on the program name in the package explorer, then select Run As and then select 1. Android application. See how a short message is shown on the screen as you press play. Now let us attach similar listeners for the other buttons, like so pauseButton.setOnClickListener(new OnClickListener() { • • @Override • public void onClick(View v) { • // TODO Auto-generated method stub • Toast. makeText(MainActivity.this, "Pausing", Toast.LENGTH_ SHORT).show(); • } • }); •
•
stopButton.setOnClickListener(new OnClickListener() { • • @Override • public void onClick(View v) { • // TODO Auto-generated method stub • Toast.makeText(MainActivity.this, "Stopping", Toast. LENGTH_SHORT).show(); • } • }); •
Now every time you press the Pause or Stop buttons, you get a similar message. Now that we know when the buttons are clicked, we need to understand what we might do when we click them. For this we need to copy the music that we want to play to a new folder under resources. Lets begin by creating that folder, right click
48 Developing for Android on 'res' in the Package Explorer and then select Create new > Folder. Over there type 'raw' as the folder name. See how the folder pops up under the res folder. Next, select the music file you want and rename it to something simple, like a.mp3 (note, you might face some difficulty with complex names and upper case characters, so rename it to something really simple like a.mp3) and then drag and drop the file to the raw folder in eclipse. You will be asked to Copy the file and then hit Okay. Notice how the file now appears in the raw folder. Next to play that object we need to create a MediaPlayer object, so to do that declare the following as a Class variable (just under public class MainActivity extends Activity { )
â&#x20AC;˘
MediaPlayer mMediaPlayer;
Then initialise it in in onCreate, preferable just before you get a reference to those buttons but after setContentView. â&#x20AC;˘
mMediaPlayer = MediaPlayer.create(this, R.raw.a);
Here we are creating a new MediaPlayer object and using the a.mp3
Developing for Android 49 file we copied in the raw folder to initialise it. Now that we have initialised the object, we need to start playing it when we click the playButton. To do that we need to inside the onClick method of the OnClickListener for the play button and write the following: •
mMediaPlayer.start();
This tells Android to start playing the music. Similarly to pause and stop the music add the following inside the onClick method of the listeners for the pause and stop buttons respectively like so: • • • • •
inside the pause button listener: mMediaPlayer.pause(); inside the stop button listener mMediaPlayer.stop();
There you are all set, save the program and run it. Hit play and there, you can start listening to the music file. In case you are not able to hear anything, make sure to un-mute your speakers :D Notice how pause and stop work great as well, also note how you
50 Developing for Android can play after pausing a file right out of the box. So here we looked at how we used the basic Android concepts to create a simple program where we were able to play pause and stop playing music in almost no time.
Download
Developing for Android Interested to learn more about Android x86 Development Platform then visit below links: Register at Intel Android Developer Zone to get latest information about Android on x86: http://software.intel.com/en-us/android∙ Coding Android Game App to support Intel x86? Here are some examples: http://software.intel.com/en-us/articles/coding-android-game-app-to-support-intel-x86-here-are-some-samples∙ Creating and Porting NDK based Android Apps on Intel Architecture: http://software.intel.com/en-us/articles/intel-for-android-developers-learning-series-7-creating-and-porting-ndk-based-android∙
Chapter 4
GUI Development The user interface (UI) on the Android platform has changed drastically over the past few years. It went from being a conservatively designed platform to something that was really modern and beautiful. Given the heightened focus on UI design and the look and feel of the app, it's critical to get UI design right. Keeping that in mind, let's look at the fundamental building block of user interfaces in Android.
52 GUI Development
Views As discussed Views are the foundational user interface elements in Android. In the previous chapter, we had created a particular ViewButton and here we shall take a look at more such views. TextView is one of the most basic View elements in Android and represents a display of text on the screen. EditText is a similar control but one where you can edit or enter text. A Button, as the name suggests, is a control which allows users to press or click it. Similarly, a CheckBox is a two-state button that can either be in a checked or unchecked state. A RadioButton is similar to a Checkbox; but unlike a CheckBox, once a RadioButton is checked, it cannot be unchecked. A Spinner is the equivalent of a DropDown menu in forms, it can have many options and the user can select one amongst them. Now there are two basic ways of creating/displaying a view, one in XML and the other one in code. Let's look at how we can do both. The first way of defining a View is in XML, this way this conforms to the Model View Controller architecture and separates the View definition and declaration in a separate area.
In this case, to define a TextView we need to create a TextView element as follows: â&#x20AC;˘ â&#x20AC;˘
<TextView android:id="@+id/mytextbox"
GUI Development 53 android:layout _ width="wrap _ content" android:layout _ height="wrap _ content" • android:text="This is a text box" /> • •
Here the TextView elements has many attributes, the android:id attribute assigns a unique id to this TextView, the layout_width and layout_height attributes specify the width and height of the element, in this case, "wrap_content" means that the TextView will adjust its width and height based on its content. Finally the text content of the TextView is specified by the android:text attribute. In a similar way, one can create similar elements for EditTexts, Buttons and other Android Views. The second way of declaring/defining a View is through code, as follows: • TextView tv = new TextView(this)
Although this is not the primary way of defining a UI in Android, at times it is very handy as you might want to add, update or remove views dynamically.
Events Just like Java, in Android user interactions like a click, long click etc. are classified as events and we can intercept events generated by Android by using EventListeners. For example, one of the most commonly used EventListener is the onClick() event listener and this is called whenever a View (like a Button, TextView etc.) is clicked. Similarly the onLongClick() event listener is called whenever a user touches and holds a View. As seen in the previous chapter, we can create an OnClickListener and attach it to a button to receive callbacks on these events. For example • Button playButton = (Button) findViewById(R. id.button1);
54 GUI Development playButton.setOnClickListener(new OnClickListener() { • @Override • public void onClick(View v) { • // TODO Auto-generated method stub • Toast. makeText(MainActivity.this, "Starting to play", Toast. LENGTH _ SHORT).show(); • mMediaPlayer.start(); • } • •
•
});
Layouts Next, lets have a look at Layouts. Layouts define the overall structure of the User Interface and define how individual Views like TextView, EditText and the like are placed in the overall User interface of the application. So layouts are primarily a group of Views and are formed from the 'ViewGroup' class. Now there are a lot of different subclasses of ViewGroup and each of them provides a very different way of displaying the Views in them. While on the subject of Views, let's consider them. What follows is a list of the most popular Views.
Add text to your app
GUI Development 55
LinearLayout A LinearLayout is a layout where the children are arranged in a single horizontal or vertical row. So for example, if you want TextView, an EditText, an ImageView and a Button is a straight t vertical line, we can use a LinearLayout as follows: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/ android" • android:layout _ width="fill _ parent" • android:layout _ height="fill _ parent" • android:orientation="vertical" > • •
•
<TextView android:layout _ width="fill _ parent" • android:layout _ height="wrap _ content" • android:text="This is sample text" /> • •
•
<EditText android:layout _ width="fill _ parent" • android:layout _ height="wrap _ content" /> • • •
<ImageView android:layout _ width="wrap _ content" • android:layout _ height="wrap _ content" • android:src = "@drawable/sampleimage" /> • •
•
<Button android:layout _ width="wrap _ content" • android:layout _ height="wrap _ content" • android:text = "Submit"/> • •
• •
</LinearLayout>
Here we have defined a Vertical LinearLayout where each of the children either has the width of its parent or has a width that depends on its content.
RelativeLayout Next, lets have a look at a RelativeLayout. Here the location of children are defined relative to each other or relative to their parent. Take
56 GUI Development this for example: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/ android" • android:layout _ width="match _ parent" • android:layout _ height="match _ parent" > • •
• • • • • • • • • • • • • • • • • • • • • • • • • • • •
<TextView android:layout _ width="fill _ parent" android:layout _ height="wrap _ content" android:layout _ alignParentTop="true" android:text="This is sample text" /> <Button android:id="@+id/button" android:layout _ width="wrap _ content" android:layout _ height="wrap _ content" android:layout _ alignParentBottom="true" android:text="Submit" /> <ImageView android:id="@+id/image" android:layout _ width="wrap _ content" android:layout _ height="wrap _ content" android:layout _ above="@id/button" android:layout _ alignParentLeft="true" android:src="@drawable/sampleimage" /> <EditText android:layout android:layout android:layout android:layout </RelativeLayout>
_ _ _ _
width="fill _ parent" height="wrap _ content" above="@+id/button" toRightOf="@id/image" />
Here we have a TextView at the top of the page and a button at the bottom of the page. THe ImageView is put at the top of the button (at the bottom of the page) and aligned to the left of the page. The EditText is put above the Button but to the right of the ImageView.
GUI Development 57 Such complex UI structures can be created really easily in a Relative layout and this is without doubt one of the most powerful layouts out there. The code above will generate an app that resembles the following image:
Add text to your app
FrameLayout Next lets look at FrameLayout, a FrameLayout is a layout where all the child views are anchored to the top left of the parent by default and where you would want the Views to overlap each other. You can however change the position of the children within the parent by controlling the android:layout_gravity attribute. A good use case of a FrameLayout is to write a label on an Image. <FrameLayout xmlns:android="http://schemas.android. com/apk/res/android" • android:layout _ width="wrap _ content" • android:layout _ height="wrap _ content" > •
• • • • •
tent"
<ImageView android:id="@+id/image" android:layout _ width="wrap _ content" android:layout _ height="wrap _ con-
58 GUI Development •
/>
android:src="@drawable/sampleimage"
• • • •
tent"
<TextView android:layout _ width="wrap _ content" android:layout _ height="wrap _ con-
android:layout _ gravity="center|bottom" • android:text="Label text" /> • </FrameLayout> •
Here we have an ImageView anchored to the FrameLayout and then we have a TextView which is used to label the Image at the bottom, center position of the image.
ListView Next, lets look at some complex UI elements, the first of which is the ListView. A ListView is a ViewGroup that contains a list of scrollable Views that are created dynamically by taking data from a data source
Suggested pattern for List View. Source: developer.android.com
GUI Development 59 like a database, array etc. Let's take an example of a Twitter application, here you might have stored all the tweets, user data, location of the tweet in a database and to show the tweet, you would need to display this data dynamically from the database. As you keep on adding data in the database, you want them to be automatically visible to user without having to add each row manually. That is where you can use a ListView and another structure called an Adapter. An Adapter is an object that takes a row of data from the database/array etc and creates a 'View' for that row in the ListView. So the Adapter is responsible for gathering the necessary information about a tweet from the database and then structuring in such a way that it looks like a tweet. As you go down a ListView, the Adapter automatically gathers more data in the database and displays them in the ListView while reusing Views at the top that became invisible when the ListView was scrolled down.
GridView A GridView is very similar to a ListView but the main difference is that the list is just not a single vertical list but a two dimensional list of items. For example, to create an image gallery you can have a two dimensional list of elements backed by a GridView. Just like a ListView, a GridView is backed by an adapter which fetches the data from a database or array etc.
Menu Menus are common UI elements in Android, they can refer to the menu you see when you press the Options button on your Android phone or when you click on menu options in the Action Bar at the top of applications. There are also can be contextual or popup menus which appear when you long press on an item.
Dialogs A dialog is a window that allows the user to enter some information or to make a decision, typically dialogs prompt the user to make a decisions but at times a Dialog can also be shown to highlight that the app is processing some information or waiting for more data etc. o create a
60 GUI Development
Suggested pattern for grid view Source: developer.android.com
simple dialog we must use the AlertDialog API AlertDialog.Builder builder = new AlertDialog. Builder(getActivity());
• •
builder.setMessage("This is what you must be aware of") • .setTitle("My dialog"); •
•
AlertDialog dialog = builder.create(); then to show the dialog, you must use the show method on the dialog
• • • •
dialog.show();
Remember you can also create complex dialogs with buttons and listeners for those buttons as well. • dialog.setPositiveButton("Okay", new DialogInterface. OnClickListener() { • @Override
GUI Development 61 public void onClick(DialogInterface dialog, int id) { • // do something when the user clicks okay • } • }) • .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { • @Override • public void onClick(DialogInterface dialog, int id) { • // do something when the user says cancel • } • }); •
Inside the button's respective OnClickListener, we can specify the action that needs to be performed when the Okay or Cancel is pressed.
Notifications Notifications is one of the hallmark features of the Android platform. It is basically a message that is displayed outside the user's normal user interface. Developers can first show a notification icon in the notification tray at the top of an Android device, once the user opens the notification drawer, he/she has access to the complete notification. Starting with Android 4.1, notifications are now expandable in nature and one can expand the initial notification to show more data and even provide actionable buttons built right into the notification. A notification is typically created by using the NotificationCompat API Additional menu •
NotificationCompat.Builder
62 GUI Development builder = • • • • •
new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.musicicon) .setContentTitle("Song playing") .setContentText("Its my life");
PendingIntent pendingIntent = PendingIntent. getActivity(this, 0, new Intent(this, MyActivity. class), 0);
•
• • •
builder.setContentIntent(pendingIntent);
NotificationManager ntificationManager = (NotificationManager) getSystemService(Context. NOTIFICATION _ SERVICE);
• • • •
notificationManager.notify(1234, builder.build());
Here we create the notification using the NotificationCompat.Builder object and then give it an icon, title and text so that the notification itself is well defined.
Example of a detailed notification. Source: developer.android.com
Next we give the notification a PendingIntent, by giving a PendingIntent to the notification, you are basically giving the notification the right to perform an action on the behalf of the application. In our case,
GUI Development 63
Notification on file information during playback
we are giving the notification the right to launch our activity MyActivity when we click on it.
Additional notification
Ultimately we must use build on the NotificationCompat.Builder to create the notification and then use the NotificationManager object to actually display the notification. So now weâ&#x20AC;&#x2122;ve gotten a good understanding of all the basic View and ViewGroups in Android, with this knowledge we can build anything from the very basic to the very complex of applications.
Chapter 5
Android NDK Most basic Android apps run well on the Dalvik VM and are portable enough to run on any type of hardware even if the hardware architecture changes for example from ARM to x86. But in cases when heavy computations are to be done like computationally intensive games, which require physics simulation to be done, it would take NDK to solve the problem and uncap the kind of performance that an app cannot be achieved under the Dalvik VM. It is however not recommended simply for the purposes of developer's preferences or because the developer only knows a specific language. Actually, before even attempting to use the NDK it is suggested that a developer be sufficiently comfortable at developing in Android and proficient at both Java and C languages.
Android NDK 65 To have more clarity on what NDK really is, it should be emphasized that it allows mixing some parts of native code in C and C++ with an Android app developed in Java. It is based on JNI i.e. Java Native interface and provides headers and native libraries to interact with the user and lets you perform computations at a much faster speed natively on the hardware. This however does not change the way in which the final application is packaged and the way in which the overall application is managed in its lifecycle. It is also wrong to assume that all type of applications will benefit if the code runs natively with the help of the NDK, in fact a major drawback for many will be that it will increase code complexity exponentially and the overhead incurred by the exchanges between Native code and other parts of the application will also be significant enough that it cannot be overlooked during its execution. Android first started supporting NDK since Android 1.5 Cupcake and features like Native Activities and x86 support started coming into picture only since Android 2.3 Gingerbread. Due to this, there have been two ways to write an Android app since Android 2.3, one is to use JNI, which offers you flexibility and availability of the Android framework, while writing code using Native Activities offers the opportunity to handle application lifecycle callbacks from the native code itself. The result is that these lifecycle events like onPause(), onCreate() are handled within the native code itself but with less featues like services and content providers not being available, which need to be accessed through JNI only. The most recent release of Android NDK supports the following instruction set architectures: • ARMv5TE, including Thumb-1 instructions • ARMv7-A, including Thumb-2 and VFPv3-D16 instructions, with optional support for NEON/VFPv3-D32 instructions • x86 instructions • MIPS instructions With the help of NDK, you can take advantage of the SIMD extensions to speed up the execution of your application. These are mainly used for Multimedia applications and can provide performance gains of several orders of magnitude greater than before. The ARM instruction set extension that supports this is known as NEON, while Intel CPUs support SSE3 (Supplemental Streaming SIMD Extensions) and older versions like SSE2, SSE and MMX. There are a couple of API incompatibilities that may occur when targeting applications that utilize both of these.
66 Android NDK The Android NDK also includes a set of cross compilers and native API libraries which provide headers to be used in development of the native application. The Android official documentation lists out the libraries which are stable and safe to use, while most others are experimental and are likely to change in future versions of Android NDK. These stable libraries are: • libc (C library) headers • libm (math library) headers • JNI interface headers • libz (Zlib compression) headers • liblog (Android logging) header • OpenGL ES 1.1 and OpenGL ES 2.0 (3D graphics libraries) headers • libjnigraphics (Pixel buffer access) header (for Android 2.2 and above). • A Minimal set of headers for C++ support • OpenSL ES native audio libraries • Android native application APIS
Minimum System Requirements The Android NDK has a set of prerequisites which need to be fulfilled before we start using and installing it on your development machine. These include: • The Android SDK version 1.5 or later and version 2.3 or later if Native: Activities are to be used. This of course includes dependencies like Java JDK etc. • Operating Systems like Windows XP (32-bit) or Windows Vista (32bit or 64-bit) / Mac OS X 10.4.8 or later / Linux 32-bit or 64-bit with Glibc 2.7 or later • GNU Make 3.81 or later • Awk • Cygwin 1.7 or later, if Windows is being used The minimum API version required for development of ARM is Android 1.5 or higher, while for other platforms like x86 and MIPS, at least Android 2.3 is required. Other restrictions related to OpenGL ES also apply, wherein OpenGL ES 2.0 is only supported since Android 2.0 or later while OpenGL ES 1.1 is supported since Android 1.6 or later.
Installation The Android NDK is available from the Android developer website,
Android NDK 67 which can be downloaded specific to your development environment and operating system. Intel based x86 processors are supported only on NDK release 6b or later, while 8d is the most recent one at this time,which was last released in December 2012. The installation involves only the extraction of the compressed package which was just downloaded. This package, when extracted gives you all the relevant files related to the NDK. It also includes documentation, which is recommended to be read before you go about trying to develop an NDK application.
Bundled Sample Applications The NDK packages with itself a couple of sample applications which can be examined for a reference on how the NDK works. The provide a very good demonstration of the manner in which native code can be integrated in your application. Some of these applications are explained in the official docs as follows: • hello-jni — a simple application that loads a string from a native method implemented in a shared library and then displays it in the application UI. • Two-libs — a simple application that loads a shared library dynamically and calls a native method provided by the library. In this case, the method is implemented in a static library imported by the shared library. • San-angeles — a simple application that renders 3D graphics through the native OpenGL ES APIs, while managing activity lifecycle with a GLSurfaceView object. • Hello-gl2 — a simple application that renders a triangle using OpenGL ES 2.0 vertex and fragment shaders. • Hello-neon — a simple application that shows how to use the cpufeatures library to check CPU capabilities at runtime, then use NEON intrinsics if supported by the CPU. Specifically, the application implements two versions of a tiny benchmark for a FIR filter loop, a C version and a NEON-optimized version for devices that support it. • Bitmap-plasma — a simple application that demonstrates how to access the pixel buffers of Android Bitmap objects from native code, and uses this to generate an old-school "plasma" effect. • Native-activity — a simple application that demonstrates how to use the native-app-glue static library to create a native activity • native-plasma — a version of bitmap-plasma implemented with a native activity.
68 Android NDK
Setting up the Application Structure The application's native sources are placed in the <project>/jni/ folder. These also include any shared libraries that are being used in the application. To describe the native sources to the build system it is required that you also place the Android.mk file. Additionally you can also add the Application.mk file if you want if you want to describe the project files in greater detail. The native code can be built with the help of the ndk-build command which is available from the script in the ndk installation directory. With the introduction to Android x86 SDK, the NDK app development experience has become very smooth. Be sure to specify APP_BI:=x86 to ndk-build command to experience it yourself. Other parts of the application like Java code can then be developed in a similar way as it is done before. The only difference will be that when the application is finally packaged, these native libraries will also be bundled along with the application. NDK applications can be debugged with the help of separate tool called ndk-gdb which is available for this platform.
An overview of the NDK NDK is a tool meant for advanced app developers who know how to deal with the performance boost given by this powerful tool and use it in a manner that excessive calls to and from Java does not create too much of an overhead and that it also does not defeat the purpose of using the tool itself. Using NDK also creates the problem of maintaining the code base for each platform separately and ensure that it is compatible with each respectively. This not only increases project complexity but also multiplies the effort of the app developer in the sense that multiple code bases have to be maintained in cases when the code simply does not work by simple porting or recompiling of the source. Whats more, it can even narrow the reach of your application or some functionality tends to be lost if processor specific proprietary extensions are used for the native app development. That being said, most applications should however face no problems in supporting different platforms and might be able to work with a simple recompilation of the source code after a little bit of porting is done. In a simple NDK project, the Android.mk is used to define modules which include shared libraries or static libraries. Static libraries can be used to generate shared libraries, which are in turn packaged into the Android
Android NDK 69 application if the developer chooses to do so. The Application.mk on the other hand is used to describe the modules which are actually required by your application. Both these files can be placed under the jni folder of the Android project. The Android.mk for any project could look like this: • LOCAL _ PATH := $(call my-dir) • include $(CLEAR _ VARS) • LOCAL _ MODULE := helloworld • LOCAL _ SRC _ FILES := helloworld.c com _ test _ android _ HelloWorld.c • include $(BUILD _ SHARED _ LIBRARY) If the native code for the app is to be built for specific platforms, you can specify this in the Application.mk file, where you can mention all the target ABIs. Alternatively you can also invoke ndk-build to specify the same at the time of building the source files. For example, to build the application source for x86 devices, you can do ndk-build APP_ABI=x86. But it is usually recommended to compile the code for all Application Binary Interfaces unless you are specifically targeting a particular platform by using the “all” parameter like ndk-build APP_ABI=”all”. To use native code in a java file, it has to be declared first and then the library can be loaded. This can be done as follows: • private static native String printhello(); • static {System.loadLibrary(“helloworld”);} The above code for example declares and loads a sample helloworld library which just returns a string that can be used anywhrere in the code. It can be used to display the message in a textview as follows: • TextView tv = new TextView(this); • tv.setText(printhello()); • setContentView(tv); To make sure that this native code can be called from Java, we need to ensure that it complies with the JNI specifications. This can be done with the help of the javah tool which helps generate headers based on the java sources. It requires that the files be compiled before running this command, which could look like: • javah -d jni -classpath bin/classes com.test.android.HelloWorld Now all we need to do is create the source file that imports the generated java header file and implements a method corresponding to the one in the headerfile that forms the body of the method that we called from Java.
70 Android NDK A simple method that returns a “Hello World” string would look like the following in the native C code: • #include “com _ test _ android _ HelloWorld.h” • JNIEXPORT jstring JNICALL Java _ com _ test _ android _ HelloWorld _ printhello • (JNIEnv * env, jobject jObj) • { • return (*env)->NewStringUTF(env, “Hello World!”); • } Now, as mentioned before the file can be compiled with the help of the ndk-build command after which the application can be compiled and packaged into an apk. The package can then be installed on an emulator where it can be tested if it is running correctly. The example shown above is fairly straightforward and definitely very easy as compared to what you would do in a real application, but a Hello World program is definitely the best way for getting an idea of how everything works and to check the basic functionality of any platform. There are however a couple of things that you need to ensure you take care of while porting your native application across platforms like ARM to Intel. These include things like toolchain compatibility (if the application is using any tools directly instead of Android build scripts), SIMD API incompatibilities between SSE and NEON and also some memory alignment implications that may occur when data is not explicitly aligned between the two architectures. The manner in which floating point operations are handled differently by each platform might also have an impact on the support for each of them. In conclusion, while the Native Development Kit is a powerful tool, it is also something that needs to be made use of correctly. While some applications surely might benefit with its presence, it is something which should only be used really needed. This is because most applications are best left running on the Dalvik VM itself without encountering any unnecessary complications with the hardware unless it hampers the development of a specific type of functionality that you would like to provide.
Chapter 6
Developing for Android x86 Due to its open source roots in the Linux kernel, Android has always been a major attraction of hobbyist developers and 'modders' who like experimenting with their devices. This has resulted in Android being used and ported to other devices and platforms. Before Intel officially announced support for Android and its partnership with Google, there were already quite a few community projects which were in progress to make Android work on x86. Now that official support is available, needless to say some of them have either lost relevance or gave gained momentum as better support has become available.
72 Developing for Android x86 One such effort is the Android-x86 project which best represents the most popular and successful port of Android to x86 devices before it was announced by Intel officially. The aim of this project was to port Android Code to x86 devices and it did enable a couple of devices such as the Asus EEE PCs, Viewsonic ViewPads, Dell Inspiron Mini and Lenovo ThinkPad Tablets to boot and run Android natively. Now that it is officially supported by Intel, there have been efforts to enable booting of Android even on Desktops (even though it wouldnâ&#x20AC;&#x2122;t make much sense). Initially this project started with the aim of consolidating different patches for x86 that were available in the open source community, but eventually development was spearheaded to enable full fledged support for some of the above devices. The latest build supports 3.0.36 linux kernel, wifi, bluetooth and ethernet, ALSA audio, external monitor and netbook native resolution. The website for this project is available at www.android-x86.org where more information and details can be accessed. The project is still active and developers are working on porting the JellyBean 4.2 code along with an effort to enable OpenGL hardware acceleration for intel and radeon devices.
Moorestown & Medfield Platforms Moorestown is Intel's smartphone platform, which it introduced in 2010. It's based on the Lincroft SoC and an Atom processor core. It focussed on better power management, with upto half the idle power consumption as compared to earlier devices. Intel announced a partnership with Google in 2011, and with version 3.1 (Honeycomb), and SDK revision 12 official support for x86 devices was added to Android. Only in Jelly Bean 4.2 and Android SDK level 17 was the emulator released with native x86 support, which allowed it to run at almost native speeds on the desktop. In early 2012, a major overhaul in Intel's architecture was announced with the Medfield platform, which was the fourth generation of Intel's mobile device technology after Moorestown. It featured a 32nm processor chip which was later known as the Intel Atom Z2460 which was accompanied by a smartphone reference design to ease the amount of effort spent by device manufacturers. It was the first ever platform that eventually got popular with leading manufacturers taking it seriously with devices like Lava XOLO X900, Lenovo K800, ZTE Grand X IN, Motorola Razr i and others being announced and released in the market. The Lava XOLO X900 is one of the first devices which was released in
Developing for Android x86 73 India in April 2012 by the domestic Indian brand of the same name. It featured an Intel Atom Z2460 1.6GHz processor with 1GB RAM and a 400MHz PowerVR SGX 540 GPU with 512KB L2 Cache along with a dual channel LPDDR2 memory interface. The phone fared well in terms of Javascript performance as it lead the pack in tests like BrowserMark and SunSpider, where it beat phones like the Samsung Galaxy Nexus, iPhone etc., while it fared decently while giving a tough competition to other phones in the battery department.
Comparing x86 and ARM Android makes it very easy to develop apps and make them able to run anywhere without any problems on almost any platform as long as they are free from native code and are dalvik based. This makes app development easy and worth the effort as apps become portable without any effort and being compromised much on performance. But when the Android NDK and JNI come into picture, the developer needs to make sure that they factor in support for all platforms. Sometimes the effort is only restricted to recompiling the application package, though it may take more in other cases where a proprietary ARM specific feature was previously implemented. Still, according to Intel's official documentation more than 75-80% of apps rely on Android SDK to run apps on top of Dalvik VM, resulting in the widely accepted fact that a majority of Android's applications are already available of Intel x86 based Android because they are platform agnostic. Though Android supports both x86 and ARM, it has generally been an unwritten rule that x86 has traditionally been much more successful on the desktop market because of its impressive performance, while ARM has been leading in the land of smartphones and tablets with its much better power management and optimisations for the mobile environment. This stereotype is set to become a thing of the past now, since Intel has been ramping up its efforts towards innovation in the mobile segment. This is likely to result in a number of developments related to better performing Intel Atom processors which is likely to benefit other ecosystems too like Windows 8, Embedded Linux and others, in addition to Android. The fact that porting desktop apps to Windows and Android tablets will become much easier is an attractive proposition for many developers and will surely result in some innovative features related to desktop integration. If a comparison between the two architectures has to be made, it makes more sense start with a table that accurately describes the main differences
74 Developing for Android x86 in the fewest words: Saltwell is the microarchitecture that evolved from Bonnel which could execute two instructions per cycle. The basic difference lied in the way chips were laid out. While Bonnel was 45nm, Saltwell was fabricated to be 32nm in size. It also contained a single chip called Penwell as compared to earlier versions which were a combination of Lincroft and Langwell. This single chip design is the reason why it has made itself easily comparable to ARM than it was possible ever before. As mentioned, Saltwell uses in-order execution as opposed to ARM which results in reduced instruction execution latency. A major advantage that x86 has available to itself is the fact that a 64 bit instruction set has always been available on this platform, while ARM is still testing it in its labs which is due to reach retail in the coming two years. The Intel Hyper-threading technology further supplements better sharing of resources with more than 50 percent performance improvement due to clock cycle sharing between two threads. This technology enables the software to view a single processor as being more than one logical processor. Intel Atom processors obviously support the usual set of hardware sensors needed for a smartphone and tablet device to work satisfactorily. These include position sensors like accelerometer, gyroscope, magnetometer, proximity sensor, GPS and environment sensors like the Ambient light sensor. These sensors can be accessed with the help of Android Sensor framework.
Binary Translation When Intel first released Medfield CPUs, a big issue for many users was unavailability of NDK based apps. This resulted in a solution proposed by the company in the form of Binary Translation which allows native binaries for Android to run on Intel based devices without much loss in performance. The technology allows execution of ARM apps without having the developers to port them to the x86 architecture. The binary translator integrates with the Dalvik VM and other ARM based JNI libraries to perform on the fly binary translation operations in such a way that it is completely transparent to the app and the underlying hardware. Intel says that it has resulted in more than 90 percent of Play store apps being able to run on Intel based phones.
OpenGL ES on Intel Atom processors The main graphics API for 3D rendering on Android is OpenGL ES, which is an specialized version of OpenGL, which was originally designed of
Developing for Android x86 75 desktop graphics processing. It has been specifically designed keeping mobile devices like smartphones and tablets in mind. Ever since the NDK was released in Android 1.5 Cupcake, OpenGL has been a vital part of the Android ecosystem for game development. It was since Android 2.2 Froyo that OpenGL ES 2.0 was available for Android development. Support for OpenGL development on Intel Atom devices has been available in Android Gingerbread 2.3.3 and consistently ever since Ice Cream Sandwich 4.0.3. One limitation for Intel devices however is that the Android emulator does not yet support development on OpenGL ES 2.0 and is restricted only to versions 1.0 and 1.1. But Intel does provide an important tool to accompany it in the form of the Intel Graphics Performance Analyzer, which runs on both Windows and Ubuntu desktops and can aid developers in getting important performance metrics related to graphics on Android smartphones and tablets. Further down the line, just recently OpenGL ES 3.0 got released, though support for which looks a little further away in time. In addition to the graphics performance analyzer discussed earlier, Intel provides the Hardware Accelerated Execution manager and Intel Atom x86 System Image for Android. The Hardware Accelerated execution manager is a hypervisor that allows much faster Android emulation than is normally possible, by running its driver on the host machine as well as within the emulated Android system. The software is available for all the three plaforms namely, Windows, Mac and Linux. It also efficient use of GPU by routing 3D computations through the host machine's GPU device. The only limitation is that it does not work for Android platforms where the Intel's x86 system Image is not available. Advantages / Disadvantages of using x86 images for development Pros 1. The main advantage of developing for x86 devices for development is the fact that targeting a mobile device which has the same architecture as the development machine has its own advantages. Whether they might be in the form of better emulation or faster execution, it just makes the development process much more easier. 2. The kind of tools, dedicated software and support that Intel is likely to provide for its platform to encourage developers to start developing apps will be much better than its ARM counterparts, which is admittedly more popular due to the wide range of devices available. 3) The x86 architecture is already more mature and has various stand-
76 Developing for Android x86 ardized interfaces such as SATA, PCIe, USB, HDMI, Firewire working with it for many years. 4. The fact that Intel devices offer better performance than its ARM counterpart cannot be denied. Though power management is admittedly a little lacking in mobile devices, Intel's x86 platform has been known for its expertise in the server and desktop space. Cons 1. Reaching the hands of a majority of consumers has to be the focus of the company and it will automatically attract the development community. 2. While porting most native apps is a no-brainer, other app developers need to make a significant effort to support both the platforms on the present and future versions of the app. 3. Even if developing the app itself might be easy, testing for bugs and patching existing bugs might become difficult and take more time as more than one hardware architectures are involved. 4. Binary Translation is a good alternative but the performance for highly computing intensive apps is not good and the criteria of what kind of apps might/might not be supported is not very clear.
Creating a native app for Intel Architecture In this tutorial, we'll look at creating NDK based apps for Intel Architecture (IA), and also consider simple use cases for porting existing NDK-based apps to IA based devices. We assume you have already installed the Android development environment including the Android SDK, Android NDK and configured emulator-x86 to test the apps. For further information, refer to the Android Community section on Intel website (http://software.intel.com/ en-us/android). To keep our development environment simple, we will use Linux* command line tools for the most part.
Creating Default Android Project Android SDK has command line tools to generate default project structure for a typical hello world app. We will first create a default project, and then modify the java sources to add JNI calls and native code. As we've seen above, we first created a directory called labs/lab2 and used “android” command line tool to generate the default project. We specified android-15 as the API level, and named our app as “CPUIdApp” with package com.example.cpuid.
Developing for Android x86 77 We then used the “ant” command line tool to build the project in debug mode and install using “adb” (or reinstall if exists on emulator or target). We assume you have already have an emulator or a device attached and it is the only listed device in “adb devices” command output. Below is a screenshot of the Android x86 emulator with ICS after completing the above process. Clicking on the App, you can see the default hello world output of the app. We will now modify the app to use native code.
Invoking Native code from java sources The default android project generates the java sources for a typical hello world project with give package namespace (eg: com.example.cpuid). To use native c/c++ code in our java source file, we first need to declare JNI call and load the native library, as highlighted yellow box in the screenshot below.
78 Developing for Android x86 As seen in the declaration, the native call returns a java string which we can use anywhere in our java source. As shown in above screenshot, we modified the TextView to display the string we get from the native call. This is highlighted in red in the box. This is a very simple case for declaring and using JNI native calls in Android App Java sources. Next, we will use “javah” tool to generate the JNI header stubs for native code, and add or modify native code to comply with JNI native headers.
Using “javah” to generate JNI header for native code We now have to modify our native code to comply with JNI call specification. “javah” too helps us automatically generate the appropriate JNI header stubs based on the Java source files. The “javah” tool requires the compiled Java class file for generating the headers. So we use the “ant” tool to quickly generate java class files as shown in below screenshot (“ant debug”). Use “javah” to generate the jni header as shown in the screenshot (second yellow highlight box). It will create a directory “jni” and the header stub based on Java class. The screenshot below shows the generated JNI native
header stub. Create corresponding C source file (“com_example_cpuid_CPUIdApp.c”) for the above generated header. Following below is the source listing : We call the native code cupid_parse and return the parsed buffer as JNI string. We are now ready to compile the native code using the x86
Developing for Android x86 79 NDK toolset.
Building native code with NDK for x86 Please refer to the Android community section on Intel website (/en-us/articles/ndk-for-ia) for more information on NDK for IA installation and usage. Android NDK toolset uses a build system, which requires a custom android specific make file “Android.mk” to be present in the “jni” folder of the project to compile native code. Android.mk specifies all the native C/C++ source files to be compiled, the headers and the type of build (eg: shared_library).
Below is the native code Android make listing for our project (“jni/ Android.mk”) This is a simple scenario with 2 C source files and specifies to build a
shared library. We can now issue “ndk-build APP_ABI=x86” to build our native code, and generate the shared lib. Android build system also provides
80 Developing for Android x86
another supplementary make file “Application.mk”, which we can use to specify additional configuration options. For example, we can specify all the supported ABIs in the Application.mk file, and the ndk-build will generate
native shared libraries to target all architectures. The screenshot above shows the successful compile of native code for x86, and also shows shared library being generated and installed. We are
now ready to rebuild our Android App, and install/run on x86 emulator or target device.
Rebuilding, Installing and Running the NDK App for IA We can use “ant debug clean” to clear our old build files, and issue “ant debug” again to start off full rebuild of android project. Use “adb” to reinstall the app on target device or x86 emulator as shown in the screenshot below. The screenshot below shows the App icon inside the x86 emulator, and
Developing for Android x86 81 the result of running the app inside the x86 emulator. We have successfully built NDK based android app start to finish. Using x86 NDK toolset to port existing NDK Apps to IA based devices. Android Apps with native code typically have a standard project structure, with “jni” folder containing the native sources, and the corresponding Android.mk/Application.mk build files. In the previous section, we saw a simple example with native source code and corresponding Android.mk file.
Android NDK toolset lets us specify all the target ABIs in Application.mk at once, and automatically generates native shared libraries for all targets. The android build system will automatically package all the target native libraries inside the APK, and at install time the Android package manager will install only the appropriate native library based on the target architecture. We can invoke “ndk-build” or specify in Application.mk APP_ABI := all
OR APP_ABI := armeabi armeabiv7a x86 Please refer http://developer. android.com/sdk/ndk/index.html for more information.
Chapter 7
Debugging on Android When you create an Android app, it is important that you deliver good quality apps that are rid of bugs and are safe to run from the userâ&#x20AC;&#x2122;s perspective. Eventually you might come across that odd error or a situation when your app is not working in the way that you expected it to be. Often these situations are difficult to sort out unless we have proper debugging tools available to us.
Debugging on Android 83 These tools allow you to step through each line of code and examine the value of each variable at that point in time with their help. The debug mode also allows you to set up breakpoints, pause execution, and offers other powerful tools to point out the problems occurring in your code. Debugging is not a big deal for people who already come from a related programming background like Java, and it will be even better if you have done debugging before in eclipse. In that case, there are only some android specific tools and techniques that you need to be aware of. The Dalvik VM in Android supports JDWP or Java Debug Wire Protocol to attach to the device over adb. Adb or Android debug bridge is a command that is often used to communicate over the debug channel with a connected phone or a virtual device such as an emulator or virtual machine. The adb command works in the form of a client server model where an instance runs on each – the client as well as the receiving server i.e. the device to which communication is being established. The adb is part of the platform tools package in the android sdk and should be available in the relevant subdirectory, which needs to be added to your PATH variable if you need access to adb easily from anywhere.
Setting up ADB To set up adb, we need to complete the following steps: 1. Make the application debuggable by mentioning it in the Android Manifest. This is done by default for all apps in the eclipse IDE. If that is not the case, you can do it manually by adding android:debuggable="true" to the <application> element of the AndroidManifest.xml file. 2. Enable debugging on the device to be connected. This can be done by going to an option similar to Settings > Applications > Development > USB Debugging on the device. Actual menu options may vary a little depending on the actual device and the manufacturer. 3. To make sure that the computer can detect the device, we need to make sure that we either install a USB driver for ADB if we are using Windows or that we add it to the udev rules for USB. Individual OEM USB drivers for Windows are available for each manufacturer and are listed in the official documentation. To install the drivers on Windows 7 for example : • Connect the device to the computer • Right click My Computer and click Manage.
84 Debugging on Android • Go to Devices > Other Device and right click on device and select Update Driver Software. • You should see an option to “Browse my computer for driver software” which you need to click on and point it to the location of your driver installation file. For Ubuntu Linux • Create the following file as root, by executing the following command: • sudo vi /etc/udev/rules.d/51-android.rules • •
• Add the following line for each vendor : SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666", GROUP="plugdev"
The information in the above line, like the vendor ID depends on your device, a list for which can be found on the Android developer website. Change permissions for the file you just created, as follows : • chmod a+r /etc/udev/rules.d/51-android.rules
To check if adb is able to connect properly, execute the adb devices command which should give you an output of all the connected devices. Using the Dalvik Debug Monitor Server (DDMS) The Dalvik Debug montior Service or DDMS as it is known is one of the application debugging tools that must be a part of every Android app developer's toolkit. It is a very powerful debugging environment and offers various unparalleled debugging features like allocation tracking, thread and heap information, logcat monitoring, Call / SMS / Location spoofing, File explorer etc. It is available by default in the Eclipse IDE environment as a separate perspective and works on top of adb for device communication. DDMS can be started from the Eclipse IDE itself by changing the perspective to DDMS by going to Window > Open Perspective > Other > DDMS. It can also be launched as a standalone application as part of the Android Device Monitor by typing the monitor command in the terminal. Note that earlier DDMS could be started independently with the help of ddms command, which now appears to be deprecated. The new Android Device monitor application offers DDMS and a couple of other debugging tools like the Hierarchy Viewer, Pixel Perfect and Tracer for OpenGL ES in a single environment. The Android Device Monitor is a standalone tool which can be used in case you do not use the Eclipse development environment, though the integration with Eclipse is something that other IDEs could be envious of. DDMS works by connecting a debugger to the debugging port of each
Debugging on Android 85 Android VM, which is associated with each process in the system. When a debuggable VM (or process) is started, the DDMS assigns the 8600 port to the first VM and then keeps assigning similar port numbers for each additional VM. Additionally 8700 is used as the base port by default, which is used to accept traffic from any other debugging port and forward it to the debugger on port 8700. This functionality has the advantage of debugging all VMs on a single port. Which traffic gets forwarded is dependent on the currently selected process in DDMS. In case IDEs other than eclipse are being used, it should be configured to attach to whatever port is assigned to the VM or it can be configured to use 8700 as the base port.
DDMS View components DDMS offers a set of view components, each of which show relevant information related to the connected physical device or emulator.
Devices The devices pane shows the details of each process that is running in the connected device. There are various operations that can be performed from this view with the help of the icons that we can see along the right of the tab. Each of these icons performs the following functions: • Debug Process Icon – It shows the state of con- The Devices view showing list of processes nection of the debugger – Red means disconnected and Green means Connected. • Update Heap – Clicking on this enables Heap information for the process so that we do not have to do memory deallocation manually. • Dump HPROF File – Generates a Heap dump, useful for tracing memory leaks in your app. • Cause GC – Invokes the Garbage Collector to collect heap data. • Update Threads – Shows information about the running threads in the Thread tab for the selected process.
86 Debugging on Android • Start Method Profiling – Tracks the metrics related a method. It collects information like the amount of time taken to execute a method, number of calls made. • Stop Process – Stops the currently selected process. • Screen Capture – Takes a screenshot of whatever is displayed on the screen. • Reset adb – As the name suggests, resets adb to reconnect to the device. Can be used if you are facing problems.
Threads The threads tab on the right of devices view shows information related to the threads for each process selected in the devices view. The information shown can be described as follows: ID – A unique ID assigned to each thread by Dalvik VM, which are only odd numbers that start from 3. Tid – The Linux thread ID associated with each thread, which matches the process ID for each main thread in a process. Status – Status of the thread in the VM, out of which daemons are marked with an asterix. Other values can be among running / sleeping / monitor / wait / native / vmwait / zombie / init / starting. Utime – Time spent executing user code. Stime – Time spent executing system code. Name – Specifies the name of the thread.
Heap The heap view shows information and statistics about the memory heap. This is important from the memory usage tracking perspective for each process and helps to track heap usage at a single point of time and gives you an overview of the overall heap usage of the app. To view Heap usage, you can follow these steps: 1. From the devices view, select the process for which heap usage has to be examined. 2. Click on Update Heap. 3. From the heap Tab, select Cause GC to enable collecting heap data. Every time you need to update you heap statistics, you can then click on Cause GC to update the statistics again.This will show object types with the amount of memory allocated to each.
Debugging on Android 87
The heap view showing info about memory heap
Allocation Tracker The allocation tracker shows real-time information about allocations happening in the application over a certain period of time. To enable allocation tracking: 1. Select the process to be tracked from the devices view. 2. Click on Start Tracking from the Allocation Tracker tab on the right pane. 3. Perform any actions on the device or emulator that you want to be tracked. 4. Click on Get Allocations to view the list of allocated objects since tracking was enabled.
Network Statistics The network statistics tab allows you to track and optimize the amount of network data that your app is using. It even allows you to tag network sockets so that you can differentiate between different types of data. The collected statistics are then displayed in the form of received and transmitted byte figures and also as a graph for the same that indicates the speed and amount of data received / transmitted.
88 Debugging on Android
Emulator Control One problem with testing Android devices using an emulator or developer device is the fact that it is unable to examine the performance of the app in real world conditions, like when a call or SMS is received / sent or when a particular location is reached. To test these real world conditions, the emulator enables you to spoof these data in order to test the functionality of your application. To be specific, the emulator tab allows you to emulate the following real world conditions in the emulator:Telephony Status : As per the official documentation, following options are available to set the status of the phoneâ&#x20AC;&#x2122;s network : Voice - unregistered, home, roaming, searching, denied Data - unregistered, home, roaming, searching, denied Speed - Full, GSM, HSCSD, GPRS, EDGE, UMTS, HSDPA Latency - GPRS, EDGE, UMTS Telephony Actions: Telephony actions allow you to spoof network actions such as sending / receiving a call or an SMS. Location settings: Emulator control allows for location spoofing with the help of location settings. These allow you to specify location manually or with the help of a GPX / KML file.
The emulator control view lets you control telephony and location for the device
Debugging on Android 89
File Explorer The file explorer view lets you view the directory and file structure if the device and also easily copy files to and from the emulator so as to enable easy data transfer in a manner similar to adb push or adb pull command. The Push file and Pull file options are available as a wrapper in the File explorer view on top of these very commands. LogCat Viewer Android has a highly developed logging system in the form of LogCat which outputs all the system messages, exceptions, Application specific information etc. Logcat for a device can be accessed with the help of the adb logcat command or with the help of DDMS in the Logcat viewer. There is so much information available through logcat that sometimes it becomes important to filter out information according to a log tag, log message, process ID, application name or log level. These options allow you to easily customize the type of log output you get and hence troubleshoot the application according to your needs.
Lint Lint is a static code analyzer that checks for possible optimizations, bugs and structural integrity of the code. It is integrated with the Eclipse IDE by default and is also available for integration with other IDEs like IntelliJ Idea. It basically supplements the development by making suggestions to improving unused resources, internationalizations etc. Each error or suggestion is accompanied with a severity level that signifies how serious the problem or error is. Lint has been developed to be IDE independent and can possibly be integrated with other IDEs too, if not already available. In most cases though, it can be run from the command-line. In case of eclipse, it runs automatically when an APK is exported, XML file is updated or changes are made in the layout editor and displays the output in the Lint Warnings view. Lint can be configured to check only a specific set of files or ignore a particular file, if needed. Such lint preferences are saved in the lint.xml file which is stored in the projectâ&#x20AC;&#x2122;s root directory. However, in case of eclipse this is not needed as the IDE automatically handles these preferences which can be edited at the project level (from the Lint Warnings view) or at global level (go to Window > Prefernces > Android > Lint Error checking).
90 Debugging on Android
`The file explorer view lets you access files from the device
Hierarchy Viewer The hierarchy viewer is another tool available from within eclipse or as an independent utility with a motive to optimize, inspect profile and debug the layout of an Android app. Before trying to run hierarchy viewer, you need to make sure that the application is installed and running in the emulator and that the debugger is not connected or trying to debug the app. After running hierarchy viewer, select the Activity and click on Load View Hierarchy. As expected, it will show you a hierarchy of the view objects with different panes like properties, tree overview, tree view and layout view. Each of these depicts a specific set of information: Tree Overview: The tree overview shows the entire tree hierarchy and can be used to navigate the tree view in detail on the right. It shows the entire set of tree elements in a sort of zoomed out manner which can be accessed individually from the tree view by moving the shaded rectangle across the panel. Tree View: The tree view depicts detailed information about individual views and their relationships. Information about a viewâ&#x20AC;&#x2122;s class or ID, screenshots or layered Photoshop file can be extracted from here. Properties View: The Properties pane shows a list of properties related to each view object that is selected. Layout View: The layout view shows a wireframe block representation of the layout which can also be used to navigate the tree view, alternatively
Debugging on Android 91 a specific block in this view gets highlighted when an element is selected in the tree view.
Pixel Perfect Pixel Perfect is another relatively new tool used for optimizing layout of an application. It can be accessed by clicking on Inspect Screenshot after the list of activities is displayed in the Hierarchy Viewer. It is used to examine individual pixels in the form of a magnified image of the screen layout. When Pixel Perfect is loaded, you will be able to see three panes in the screen: View Object pane: The view object pane lists all the view objects visible on the screen, whether they are part of the Android system or the app itself. Pixel Perfect Loupe Pane: This pane shows the detailed information about each pixel corresponding to the magnified image of the screen. The information available is the detailed colour codes (HTML colour codes, RGB values), X/Y coordinates etc. Pixel Perfect Pane: This pane shows the overall image of the screen as it would be seen normally. This screen is also used to position the crosshair in the Pixel Perfect Loupe pane. Pixel Perfect also allows creation of UI elements based on bitmap overlays done in the form of an image.
Traceview Traceview is a nice little utility to speed up performance of your application. It is a profiler that examines the execution logs and displays the data in a graphical form. To enable traceview, you need to have enabled tracing for your app and generated trace trace logs beforehand with the help of the Debug class. This is generally a more preferred method as opposed to another option where we generate trace logs with the help of the Start method profiling button in DDMS. Once we have trace logs available to us, these can be loaded into traceview which displays a timeline view in the form of bars that signify the execution time of each thread. It also shows a profile view which shows the most important data related to the execution time of each method in the application along with a few other statistics. There are a couple of other utilities that are available for debugging your application in a very detailed and in-depth manner. These include utilities like systrace, dmtracedump, MonkeyRunner, Tracer for OpenGL etc., which help in optimizing every aspect of the app. There are some
92 Debugging on Android
Download
utilities which you would want to check out before distributing your apps to the user like zipalign and ProGuard. Most of these tools and the ones that are included in this chapter require extensive reading of official documentation and other resources, because each of these are complex enough to have a complete tutorial dedicated to them The Pixel Perfect screen lets you take a peek at that could span a few pages. The a pixel level trick is not how to debug using these utilities, but infact extracting useful information from the raw data that these utilities make available to you and formulating an optimization strategy.The most important utility however is DDMS, which is by far the most exhaustive and is offers complete debugging and optimization environment for each aspect of the application. With Intel's focus on Android and special tools for Android app development such as Intel Hardware Accelerated Execution Manager, Intel Graphics Performance Analyzer and Intel Atom x86 system image, the development process is now greatly simplified.
Intel HAXM http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager/∙ Android Jelly Bean (4.2 ) x86 Emulator System Image http://software.intel.com/en-us/articles/android-4-2-jelly-bean-x86-emulator-system-image∙ Android Ice Cream Sandwich (4.0.4 ) x86 Emulator System Image http://software.intel.com/en-us/articles/android-ice-cream-sandwich-x86emulator-image/∙ Intel Graphics Performance Analyzer Tool http://software.intel.com/en-us/articles/intel-gpa-android-support How to debug an App for Android x86 and the tools to use: http://software.intel.com/en-us/articles/how-to-debug-an-app-forandroid-x86-and-the-tools-to-use/
Debugging on Android 93
You can monitor all necessary parameters in real time with Intel GPA
Intel Graphics Performance Analyzer The Intel Graphics Performance Analyzer is a tool for collecting performance metrics related to OpenGL based Games and graphical application for the Android as the Target platform. It suppports all the three operating systems namely Windows 7/8, Mac 10.7/10.8 and Ubuntu Linux 11.10/12.04 for Analysis. The tool can be downloaded from the Intel Website and can be installed on Ubuntu as follows: 1. Install the sharutils package before proceeding with the installation. 2. Change the file permissions of the downloaded file with the following command: chmod 755 intel-gpa _ 12.5 _ x86.deb.shar This can be done similarly for the x64 package if you are installing that version. 3. Execute the extracted deb file and install the software with the package manager. The installation for Windows and Mac OS X platform is similar, where you need to download the respective executables and follow the instructions give by the installation wizard. Before proceeding futher, you will need to set up the adb connection by installing it as instructed in the Android Debugging chapter and then provide the path to its directory in the settings dialog which can be opened after launching the Intel GPA tool and accessing the
94 Debugging on Android
Intel GPA showing charts for each metric while analysing Angry Birds
Connection Dialog. Alternatively, you can also connect to you phone over wifi, for which you need to restart adb with the adb tcpip 5555 command and then connecting to the phone by selecting it in the connection screen. That is all you need to do for the initial set up, after which you can now launch the Graphics Performance Analyzer and select the application to be debugged / analyzed. However, the respective application needs to be analyzable, for which you will need to go to the AndroidManifest.xml and change its debuggable permission to be true. When the GPA screen is opened, you will be able to see the performance metrics on the left, which are organized according to their type, for eg. CPU, Device IO, GPU, Memory, OpenGL, Power etc. The notification area shows other information specific to the connection, like the application being debugged, size of window, Vsync status and version of OpenGL ES API etc. To select a metric to be displayed in the chart, select the metric and drag it to the chart at an appropriate position. The chart area allows a maximum of 16 charts to visualize the metric values. Intel GPA can also be used to monitor custom metrics defined by you specifically for your application. Custom metrics allow you to analyze all kinds of data which includes lights in the scene, duration of post-processing pipeline stages etc. Custom metrics need to be defined in the applications source code itself with the help of OpenGL ES extensions API provided by Intel GPA itself.
95
notes
96
notes
The Intel® Developer Zone combines all the familiar tools, resources, and support from the Intel® Software Partner Program, the Intel® Software Network and the Intel AppUp® Developer Program into one premier developer program — designed to provide the development support and business opportunities developers and software businesses need to innovate and succeed.
Please visit Intel Android Developer Zone at the following link: http://software.intel.com/en-us/android/
RNI REGN. No. MAH ENG/2001/3791