Tuesday, September 24, 2013

Android Application Package (APK)


What is an apk?
Android application package file (APK) is the file format used to distribute and install application software and middleware onto Google's Android operating system. To make an APK file, a program for Android is first compiled, and then all of its parts are packaged into one file. This holds all of that program's code (such as .dex files), resources, assets, certificates, and manifest file. As is the case with many file formats, APK files can have any name needed, but must end with the four character, three letter extension, .apk.

Building and Running

During the build process, your Android projects are compiled and packaged into an .apk file, the container for your application binary. It contains all of the information necessary to run your application on a device or emulator, such as compiled .dex files (.class files converted to Dalvik byte code), a binary version of the AndroidManifest.xml file, compiled resources (resources.arsc) and uncompiled resource files for your application.
If you are developing in Eclipse, the ADT plugin incrementally builds your project as you make changes to the source code. Eclipse outputs an .apk file automatically to the bin folder of the project, so you do not have to do anything extra to generate the .apk.
If you are developing in a non-Eclipse environment, you can build your project with the generated build.xml Ant file that is in the project directory. The Ant file calls targets that automatically call the build tools for you.
To run an application on an emulator or device, the application must be signed using debug or release mode. You typically want to sign your application in debug mode when you develop and test your application, because the build tools use a debug key with a known password so you do not have to enter it every time you build. When you are ready to release the application to Google Play, you must sign the application in release mode, using your own private key.
The following diagram depicts the components involved in building and running an application:
   

A Detailed Look at the Build Process

The build process involves many tools and processes that generate intermediate files on the way to producing an .apk. If you are developing in Eclipse, the complete build process is automatically done periodically as you develop and save your code changes. If you are using other IDEs, this build process is done every time you run the generated Ant build script for your project. It is useful, however, to understand what is happening under the hood since much of the tools and processes are masked from you. The following diagram depicts the different tools and processes that are involved in a build:
         

The general process for a typical build is outlined below:
  • The Android Asset Packaging Tool (aapt) takes your application resource files, such as the AndroidManifest.xml file and the XML files for your Activities, and compiles them. An R.java is also produced so you can reference your resources from your Java code.
  • The aidl tool converts any .aidl interfaces that you have into Java interfaces.
  • All of your Java code, including the R.java and .aidl files, are compiled by the Java compiler and .class files are output.
  • The dex tool converts the .class files to Dalvik byte code. Any 3rd party libraries and .class files that you have included in your project are also converted into .dex files so that they can be packaged into the final .apk file.
  • All non-compiled resources (such as images), compiled resources, and the .dex files are sent to the apkbuilder tool to be packaged into an .apk file.
  • Once the .apk is built, it must be signed with either a debug or release key before it can be installed to a device.
  • Finally, the application is being signed in release mode.
Basic structure
Since an APK file is an archive that once unzipped usually contains the following folders structure:

            

Here’s a breakdown on what’s what:
META-INF directory:
  • MANIFEST.MF: the Manifest file
  • CERT.RSA: The certificate of the application.
  • Contains the certificate of the public key for you to verify the signature.
  • CERT.SF: It is the signature file it contains the list of resources and SHA-1 digest;
Resource folder
Contains following category of resources:
  • /drawable:   Here it stores all the  graphic files as well as android xml based styles. By default, there are several versions of folders within this such as: drawable-mdpi, drawable-hdpidrawable-ldpi. This is because there are many Android devices with different screen resolutions, hence in order to adapt to different screen resolutions these kind of folder structure is used.
  • /layout:  This folder contains the UI layouts that is used in the project. These UI layouts are stored as XML files. 
resources.arsc :
It contains the compressed resources file.
AndroidManifest.xml:
Describes the name, version, access rights, referenced library files for the application. 
classes.dex
It is a compressed file which contains the java and classes compiled.

How to build Android application package (.apk) from the command line using the SDK tools
Step 1: Generate Resource java code and packaged Resources
aapt  package -f -M ${manifest.file} -F ${packaged.resource.file} -I ${path.to.android-jar.library} -S ${android-resource-directory} [-m -J ${folder.to.output.the.R.java}]
Step 2: Compile java source codes + R.java
use javac
Step 3: Convert classes to Dalvik bytecodes
use dx.bat
dx.bat  –dex  –output=${output.dex.file}  ${compiled.classes.directory}  ${jar files..}
Step 4: Create unsigned APK
use apkbuilder
apkbuilder  ${output.apk.file} -u -z  ${packagedresource.file} -f  ${dex.file}
or
apkbuilder  ${output.apk.file} -u -z  ${packagedresource.file} -f  ${dex.file}  -rf  ${source.dir}  -rj  ${libraries.dir}
-rf = resources required for compiled source files?
-rj = resources required for jar files
Step 5: Generate a key
use keytool
Step 6: Sign APK
use jarsigner
jarsigner  -keystore ${keystore} -storepass  ${keystore.password} -keypass ${keypass} -signedjar ${signed.apkfile} ${unsigned.apkfile} ${keyalias}
Step 7: Publish
use adb
adb -d install -r ${signed.apk}
Inspecting your APK file:
aapt list -v latest.apk

Case Study on Native Android SDK
Following is the package detail for an Android native based project, where the files used at the development stage is placed mostly stored in src for java files and layouts are designed and stored in res/layout.
            
Once the apk build is generated which can be easily located in bin folder of the project. We can get the apk extracted which will have the  folder structure as mentioned in below diagram. All the source class files are zipped separately and kept in classes.dex file
         
Case Study on Convertigo MEAP
Using  Convertigo MEAP following is the folder structure followed at the time of development, the files used at the development stage is placed mostly in DisplayObjects
        
Once the build is generated and  apk is generated we get the below as its folder structure, where the
All the code used at time of development can be seen located in assets->www folder
         
Interaction between HTML, Javascript to Android native code.
This is done with help of WebView.
A WebView that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit rendering engine to display web pages and includes methods to navigate forward and backward through a history, zoom in and out, perform text searches and more.

Android APK generation using command line

Android APK generation using command line
In order to generate, we need to follow the following steps
1.      1.  Folder
Create these folders inside your parent folder named AndroidTest. Folders you need to create inside manually are

·         Assets
This folder contains all html folder.

·         Res
o   Folders you need to create manually inside this folder
o   Inside res/drawable copy app icon image, rename the image as mylogo.png
o   Inside res/values create a xml file named as string.xml
type the following code




 
 
Where myApplicationName sets the name of your app.
·         Src
o   This folder contains the package including java source
Ex: com.tt.rnd (i.e. com\tt\rnd)


o   Create a file named MyActivity.java inside your package
Ex : com\tt\rnd\MyActivity.java Paste the following code inside MyActivity.java 
 
package com.tt.rnd;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       WebView   webview = new WebView(this);
        webview.getSettings().setJavaScriptEnabled(true);
        WebSettings webSettings = webview.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webview.load--"file:///android_asset/index.html");
        setContentView(webview);
    }
}

 2.       AndroidManifest.xml You need create this file inside your parent folder. Type the below code
  

 

 

3. Download Java
The Java Standard Edition (Java SE) is available from Oracle at http://www.oracle.com/technetwork/java/javase/downloads.
Default installation location will vary between Java versions and OS platforms, so create a pointer to its location:
JAVA_HOME = C:/Program Files/Java/jdk1.6.0_26

5. Download Android
The Android Software Development Kit (Android SDK) is available from Google at http://developer.android.com/sdk.
Default installation location will vary between Android versions and OS platforms, so create a pointer to its location:
ANDROID_HOME = C:/Program Files/Android/android-sdk

6. Choose project
Locate the path to your project named- AndroidTest
DEV_HOME = C:/Users/johnd/dev/AndroidTest

7. Create keystore
A keystore is a database of private keys and their associated X.509 certificate chains authenticating the corresponding public keys. An Android program must be signed in order to execute on a device, and the program is signed by using a key from a keystore.
Use the keytool program to create a keystore:
JAVA_HOME/bin/keytool
                -genkeypair
                -validity 10000
                -dname "CN=company name,
                        OU=organisational unit,
                        O=organisation,
                        L=location,
                        S=state,
                        C=country code"
                -keystore DEV_HOME/AndroidTest.keystore
                -storepass password
                -keypass password
                -alias AndroidTestKey
                -keyalg RSA
                -v

Replace the distinguished name (dname) information with your own. Make sure to specify passwords as indicated. The key is accessed through the specified alias which can be any string.
The output of the command will be the DEV_HOME/AndroidTest.keystore file which contains one key identified by the supplied alias.
8. Create R.java
In order for the application source code to be able to access the resources within the res/ directory, a class called R.java (for Resources) is created.
Use the Android Asset Packaging Tool (aapt) to create the R.java file:
ANDROID_HOME/platform-tools/aapt
                        package
                        -v
                        -f
                        -m
                        -S DEV_HOME/res
                        -A DEV_HOME/assets
                        -J DEV_HOME/src
                        -M DEV_HOME/AndroidManifest.xml
                        -I ANDROID_HOME/platforms/android-15/android.jar
The destination location of R.java within the src/ tree is determined by the package attribute of the manifest file.


9. Compile code
Use the javac tool to compile java source code in a package:
JAVA_HOME/bin/javac
                -verbose
                -d DEV_HOME/obj
                -classpath ANDROID_HOME/platforms/android-15/android.jar;DEV_HOME/obj
                -sourcepath DEV_HOME/src
                DEV_HOME/src/com/tt/rnd/0*.java
The command must be applied for each existing package. 3rd-party .jar files from the lib/ directory must be listed in the -classpath entry. Note that on UNIX-like operating systems the classpath entry delimiter should be a colon (":").
The output of the command is .class files in the obj/ tree.
Non-java files within the src/ tree must be copied to the associated location in the obj/ tree.

10. Create DEX file
DEX ("Dalvik Executable") is the specific bytecode format understood by the Dalvik virtual machine (VM) present in all Android devices.
Use the dx tool to bundle the content of the obj/ directory as well as 3rd-party .jar files from the lib/ directory into a single .dex file:
ANDROID_HOME/platform-tools/dx
                --dex
                --verbose
                --output=DEV_HOME/bin/classes.dex
                DEV_HOME/obj
                DEV_HOME/lib
This will create the classes.dex file in the bin/ directory. The content of a .dex file can be inspected using the ANDROID_HOME/platform-tools/dexdump tool.
11. Create APK file
The Android package format (APK) is the .jar equivalent for Android. The package contains the manifest file, the resources and the classes.dex file.
Use the aapt tool to create the .apk file:
ANDROID_HOME/platform-tools/aapt
                         package
                         -v
                         -f
                         -A DEV_HOME/assets
                         -M DEV_HOME/AndroidManifest.xml
                         -S DEV_HOME/res
                         -I ANDROID_HOME/platforms/android-15/android.jar
                         -F DEV_HOME/bin/AndroidTest.unsigned.apk
                         DEV_HOME/bin
This will create the AndroidTest.unsigned.apk file in the bin/ directory. Note that APK is an ordinary archive format that can be inspected by tools like WinZip or unzip -l.
12. Sign APK file
In order to execute on an Android device, the Android package needs to be signed.
Use the jarsigner tool and the key from the keystore created above to create a signed version of the package:
JAVA_HOME/bin/jarsigner
                -verbose
                -keystore DEV_HOME/AndroidTest.keystore
                -storepass password
                -keypass password
                -signedjar DEV_HOME/bin/AndroidTest.signed.apk
                DEV_HOME/bin/AndroidTest.unsigned.apk
                AndroidTestKey
The signing process adds the META-INF/ directory to the APK archive including the signature (.SF) file and the associated PKSC file (.RSA).
The signed APK is stored as AndroidTest.signed.apk file in the bin/ directory.
13. Zip-align APK file
zipalign is an archive alignment tool that provides important optimization to Android packages. This step is optional, but recommended:
ANDROID_HOME/tools/zipalign
                -v
                -f
                4
                DEV_HOME/bin/AndroidTest.signed.apk
                DEV_HOME/bin/AndroidTest.apk
This will create the AndroidTest.apk which is the final product delivered in one self-contained unit.