Colophon
Android for iOS Developers: Java™ Edition 2018
ISBN: 978-3-906926-11-7
© Copyright 2016-2018 by Adrian Kosmaczewski – All Rights Reserved.
AKOSMA Training Adrian Kosmaczewski
Ringkengässchen 11 – 8200 Schaffhausen – Switzerland
This document is geared towards providing exact and reliable information in regards to the topic and issue covered. The publication is sold with the idea that the publisher is not required to render accounting, officially permitted, or otherwise, qualified services. If advice is necessary, legal or professional, a practiced individual in the profession should be ordered.
In no way is it legal to reproduce, duplicate, or transmit any part of this document in either electronic means or in printed format. Recording of this publication is strictly prohibited and any storage of this document is not allowed unless with written permission from the publisher. All rights reserved.
The information provided herein is stated to be truthful and consistent, in that any liability, in terms of inattention or otherwise, by any usage or abuse of any policies, processes, or directions contained within is the solitary and utter responsibility of the recipient reader. Under no circumstances will any legal responsibility or blame gbe held against the publisher for any reparation, damages, or monetary loss due to the information herein, either directly or indirectly.
Respective authors own all copyrights not held by the publisher.
The information herein is offered for informational purposes solely, and is universal as so. The presentation of the information is without contract or any type of guarantee assurance.
The trademarks that are used are without any consent, and the publication of the trademark is without permission or backing by the trademark owner. All trademarks and brands within this book are for clarifying purposes only and are owned by the owners themselves, not affiliated with this document. Android is a trademark of Google Inc. iOS is a trademark or registered trademark of Cisco in the U.S. and other countries and is used under license by Apple Inc. Java is a trademark of Oracle Corporation and/or its affiliates.
The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.
Written and published in Switzerland. Created with the eBook Template Toolchain by Adrian Kosmaczewski based on Asciidoctor and PlantUML.
Abstract
This book provides a quick introduction of Android for iOS developers using the Java™ programming language. It targets iOS developers with medium or advanced level, having shipped some iOS applications already in either Objective-C and Swift.
Dedication
To Laura.
Preface
The world of mobile development is a ground in constant motion. However, for the past five years, Android and iOS have both reached the level of dominant players in the field, moving other platforms out of sight. Due to the complexity of these systems, developers tend to concentrate their efforts in just one platform; however businesses must target both platforms to remain competitive in the mobile market.
This book provides an iOS developer’s perspective on Android, using the Java™ programming language, highlighting the similarities and the major differences between both platforms. The author hopes that these lines will help other developers to jump to the fascinating world of Android using their hard earned iOS knowledge.
Target Audience
This book is intended as a step-by-step guide to guide developers well versed in the arts of iOS into the realm of Android mobile application development.
How To Read This Book
The author assumes that the reader has never written Android applications before; at most, maybe, the reader has played with an Android device at some point, but nothing else. If you are already familiar with Android Studio and Java, you can skip directly to chapter 2, and start creating apps right away.
If you are not familiar with the Android developer tools, it is strongly recommended to read this book linearly, and to build the sample applications one after the other. This will help you build your skills step by step.
You can use this book as reference, later during your development work, using the provided source code as a basis for your own projects. The book can work as a "cookbook" text, providing specific help about some common (and not-so-common) tasks.
Requirements
This book assumes that the reader is using a Mac – after all, the reader is supposed to be an iOS developer!
It also assumes working programming knowledge in Objective-C or Swift, and of the most common iOS frameworks, such as Foundation, UIKit, Core Location, Core Data and others.
Most importantly, it is also assumed that the reader already knows Java; if not, please be aware that you might have a hard time understanding the code snippets shown in this book. The Bibliography section at the end of the book provides a few useful titles for starting your exploration of Java. In particular I’d recommend reading Bloch’s own "Effective Java" to help you take your Java skills to the next level.
In terms of software requirements, this book assumes that the latest version of Android Studio (3.0.1 at the time of publishing) is installed in the development machine, as well as Homebrew.
Source Code
The code bundled with the book has been prepared and tested with the latest version of Android Studio; make sure to download and install it in your system before starting.
All applications use the same baseline (or minSdkVersion
): API 21, also known as Lollipop 5.0. This version of Android was released in November 2014, and at the time of this writing, 80% of all Android devices in the wild run a version equal or older to Lollipop. This should hopefully give this book the wide possible reach as well as a solid foundation for the future of the platform. Similarly, all code projects target the latest Android version available at the time of publication, API 27, Oreo 8.1 (targetSdkVersion
and compileSdkVersion
in the module Gradle files.)
Every time that the text of the book references some sample code, a "Follow Along" callout section will appear with the path of the project, which you can open on Android Studio to run the project directly on your device or the emulator:
Follow along
The code of this section is located in the |
Each application is as simple as possible, but not simpler. All the applications are working examples, tested at least in four environments:
-
The official Android Emulator.
-
The Genymotion Android Emulator.
-
A OnePlus 3 Android smartphone.
-
A Samsung Galaxy Tab S2 tablet.
Given the large variety of the Android device market, it is possible that some bits and pieces of the source code will not work in some devices; I remember having trouble with some Android devices during my career, so I would not be surprised if some of you encounter difficulties. I will not be able to provide support for your particular device, but I have made every possible effort so that the code works in the environments enumerated above.
Structure
This book is structured around code. The chapters are meant to be read with Android Studio open, in the order they have been written; I have reused bits and pieces of knowledge from previous chapters in many others, so you should be better served by reading them in order.
To help readers get up and running as fast as possible, every chapter features a section called "TL;DR" at its very beginning, including a handy summary of the most important similarities and differences between Android and iOS. You can use the tables in this section as a reference, and if you find them useful you can print a copy of the Appendix C, which contains all the TL;DR tables together in the same place.
The source code included in the book points directly to the projects available in the code zip file, which contains all the sample applications showcased in the pages of this book.
Thanks
I would like to thank all the readers of the first edition of this book; your support is what made this second edition possible! In particular I would like to mention Luca Torella, Patrick Balestra and Nick K., who sent me lots of feedback and errata via e-mail and Twitter. And a very, very special shoutout to Florent Pillet who not only provided lots of feedback and errata, but actually gave me the idea of creating a Kotlin version for this second edition. Thanks a lot!
About the Author
Adrian Kosmaczewski is a writer, a software developer and a trainer. He is the author of many books about mobile software development, and has shipped mobile, web and desktop apps for iOS, Android, Mac OS X, Windows and Linux since 1996. Adrian holds a Master in Information Technology from the University of Liverpool.
When not coding or teaching, Adrian likes to spend time with his wife Claudia, his cat Max and his Olivetti Lettera 22 typewriter.
Part 1: Introduction
This first part of the book will guide the reader in the world of Android app development. We will first learn how to install and use Android Studio, we are going to get familiar with the tools and ecosystem, not only to create applications but to be able to debug them effectively.
1. Toolchain
Each platform vendor tries – and, to a large extent, succeeds at – locking third-party developers into their own ecosystem. This is true of many software platforms, and neither iOS nor Android are the exception to this rule.
One of the biggest efforts for iOS developers new to the Android ecosystem is getting used to a new set of tools, paradigms, workflows and even new keyboard shortcuts all over the place. This chapter will present an introduction to the various tools used in the everyday life of a seasoned Android developer.
1.1. TL;DR
As an introduction, these are the most important differences that distinguish the iOS developer experience from that of Android.
Android | iOS | |
---|---|---|
IDE |
Android Studio |
Xcode |
Profiling |
Android Device Monitor |
Instruments |
Preview |
Android Emulator |
iOS Simulator |
Blocks in previous versions |
Retrolambda |
PLBlocks |
Programming Language |
Java |
Swift or Objective-C |
Command Line |
|
|
Going beyond |
Rooting |
Jailbreaking |
Application metadata |
AndroidManifest.xml |
Info.plist |
Dependency Manager |
Gradle |
CocoaPods – Carthage |
Distribution |
APK |
IPA |
Debugger |
ADB + DDMS |
LLDB |
Logger |
LogCat |
NSLog() or print() |
View Debugging |
Hierarchy viewer |
Xcode view debugging |
Static Analysis |
Android Lint |
Clang Static Analyzer |
Classic programming language |
Java |
Objective-C |
Hype programming language |
Kotlin – Groovy – Scala – Clojure |
Swift |
1.2. Java
Until 2017, Android applications were primarily written in Java, a language that shares a lot of features and commonalities with Objective-C and Swift. After all, many Java engineers working for Sun in the nineties came from NeXT, the computer company founded by Steve Jobs that ultimately merged with Apple in 1996, bringing the Objective-C language to the Apple ecosystem.
Both Java and Objective-C share lots of commonalities, such as protocols (called "interfaces" in the realm of Java) or primitive boxing types such as NSNumber
(represented by the family of Number
subclasses in Java.) They also represents two opposite views in terms of compile-time checks; Objective-C delegates most method and type resolutions to runtime, while Java performs rather strict type checking. In this respect, Swift is much more close to Java than Objective-C will ever be.
Learning Java from Scratch
This book will not provide the reader with an exhaustive introduction to the Java programming language. The Bibliography at the end of this book provides some useful titles for the reader to learn more about it. |
Java has the following characteristics:
-
Single inheritance.
-
Strongly and statically typed.
-
No header files like Objective-C.
-
Objects instantiated in a garbage-collected heap; primitive values on the stack.
-
Classes, interfaces, fields and methods are "package private" by default.
-
The
Object
class is the base class for all objects in Java. -
"Interfaces" are similar to Objective-C and Swift protocols, that is, constructs equivalent to abstract classes with pure virtual methods.
-
Java has no similar concept to that of Objective-C categories or Swift extensions, that is, it is impossible to extend classes other than by inheritance.
-
Full namespace support.
-
The closest equivalent for Objective-C’s
id
or SwiftAny
types is to use cast toObject
. -
Methods can be overloaded, unlike Objective-C but like Swift and other languages.
Of all the items above, the most important is the "Strongly and statically typed" one. This means that method calls in Java are bound at compile time, instead of being dispatched dynamically at runtime like in Objective-C. In spite of this, Java resolves polymorphic methods at runtime using a "vtable," just like in C++ or C#.
Android and Java 8
Android currently only supports version 1.7 of the Java Programming Language. Version 8, which introduced many new features such as lambdas, is not yet completely supported by Android, and at the time of this writing, there has been no official announcement about its availability in the near future. |
Comparing Java to Objective-C and Swift
The table "Comparison of Java 1.7, Objective-C 2.0 and Swift 4" provides a comparison between these three languages.
Java 1.7 | Objective-C 2.0 | Swift 4 | |
---|---|---|---|
Inheritance |
Simple, with interfaces |
Simple, with protocols |
Simple, with protocols and protocol extensions |
Semicolons |
Mandatory |
Mandatory |
Optional |
Class definition |
|
|
|
Interfaces |
implements |
conforms to |
conforms to |
Including code |
|
|
|
Class extensions |
no |
Categories |
Extensions |
Dynamic typing |
no |
|
|
Private field suffix |
|
|
|
Memory management |
Garbage collection |
Manual or Automatic Reference Counting |
Automatic Reference Counting |
Generics |
yes (type erasure) |
yes (type erasure) |
yes |
Method pointers |
no |
|
|
Callbacks |
Listeners via anonymous classes |
Delegate objects and blocks |
Delegate objects and functions |
Pointers |
no |
yes |
Via library classes |
Root class |
|
|
|
Visibility |
|
|
|
Exception handling |
|
|
|
Namespaces |
Packages |
Through class prefixes |
Implicit, via modules |
Callbacks
One of the most visible differences between Java and Objective-C & Swift is the syntax for event callbacks. As mentioned above, Java 1.7 does not include lambdas, and as such it uses a feature called "Anonymous Classes" to inline the definition of event handlers and other kinds of callbacks in the code of your applications:
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doSomething();
}
});
In the snippet above, the code attaches an instance of a new "anonymous class" implementing the OnClickListener
interface; all of them (the subclass and the instance) are just created "on the fly", without the need for the developer to create a separate file and to override the required methods there.
iOS developers who remember a time before Objective-C blocks might ask themselves what is the reason for not declaring the class in a separate file, plus an interface file filling the role of a "delegate protocol" between both objects. Rest assured, this approach would be absolutely valid and possible; and in many cases it might even be recommended. However, the anonymous class approach is more idiomatic in Android (that is, you more are likely to encounter it in other projects during your careeer) and it is also extremely convenient for small projects.
The Retrolambda Project
The open source project Retrolambda allows developers to use lambdas in Java 5, 6, and 7. For those who remember the early days of iOS development, PLBlocks used to offer a similar service; being able to use Objective-C blocks in iPhone OS 2.2+ and Mac OS X 10.5 applications. |
As a convenience for the developer, Android Studio automatically displays the following shorter syntax for anonymous class callbacks, mimicking the look and feel of Java 1.8 lambdas, yielding a more readable and "future proof" experience:
mButton.setOnClickListener((v) -> {
doSomething();
});
Getting used to this syntax is going to be very helpful in your path from iOS to Android. You can switch from one representation to the other by clicking on the small +
sign in the gutter at the left side of the code editor.
Learning more about Java Lambdas
To learn more about lambdas and how they compare to anonymous classes, please refer to the official Java documentation by Oracle. |
The Android Runtime
Another important fact about Android is that, by design, the Java applications compiled for the Android operating system are not compatible with a standard Java Virtual Machine – JVM – such as the ones available for Windows, macOS or Linux. This simple fact is often overlooked but it is very important to remember.
Android and the JVM
Compiled Android Java applications are not compatibles with the standard Java Virtual Machine by Oracle. |
Android applications are compiled as DEX binaries (which stands for "Dalvik Executables") and run in a special virtual machine, optimized for mobile devices, formerly known as "Dalvik" and now most commonly referred to as the Android Runtime (ART.) Binaries targeting the ART have the following characteristics:
-
Developers can include Java code bundled in binary form, such as JARs (Java Archives) in their applications; they can also include the source files in their projects, but all of this will be compiled as Android DEX binaries, which has a different binary structure.
-
Not all valid Java APIs for a standard JVM exist under ART; in particular most of the
javax.
packages are unavailable in Android. -
DEX files are smaller than their equivalent JARs.
-
ART uses a register-based architecture, instead of the standard JVM stack-based architecture, in order to increase performance.
-
ART uses non-JVM standard bytecode instructions, and a different inter-process protocol.
-
ART can run several Android applications in the same process if required.
From Android 2.2 "Froyo" to Android 5 "Lollipop", a just-in-time compiler (JIT) had been added to the Dalvik virtual, helping it increase the performance of the final code. ART, on the other hand, single handedly compiles all downloaded apps to native code upon installation, and provides much better garbage collection and debugging facilities than Dalvik.
Compilation
The diagram "Android Application Compilation" shows how close "APK" files are to the equivalent "IPA" files distributed by the Apple App Store. In both cases it consists of a compressed archive containing both the binary of the executable and all of its bundled resources, following a very particular folder structure.
Android Release History
The following table shows the history of Android releases, borrowed from Wikipedia, combined with information from the Android developer dashboard. This information is valid as of August 2017.
Code Name | Version Number | Release Date | API Level | Support status | % |
---|---|---|---|---|---|
Alpha |
1.0 |
September 23, 2008 |
1 |
Discontinued |
– |
Beta |
1.1 |
February 9, 2009 |
2 |
Discontinued |
– |
Cupcake |
1.5 |
April 27, 2009 |
3 |
Discontinued |
– |
Donut |
1.6 |
September 15, 2009 |
4 |
Discontinued |
– |
Eclair |
2.0 - 2.1 |
October 26, 2009 |
5 - 7 |
Discontinued |
– |
Froyo |
2.2 - 2.2.3 |
May 20, 2010 |
8 |
Discontinued |
– |
Gingerbread |
2.3 - 2.3.7 |
December 6, 2010 |
9 - 10 |
Discontinued |
0.4% |
Honeycomb |
3.0 - 3.2.6 |
February 22, 2011 |
11 - 13 |
Discontinued |
– |
Ice Cream Sandwich |
4.0 - 4.0.4 |
October 18, 2011 |
14 - 15 |
Discontinued |
0.5% |
Jelly Bean |
4.1 - 4.3.1 |
July 9, 2012 |
16 - 18 |
Discontinued |
5.9% |
KitKat |
4.4 - 4.4.4 |
October 31, 2013 |
19 - 20 |
Discontinued |
13.4% |
Lollipop |
5.0 - 5.1.1 |
November 12, 2014 |
21 - 22 |
Supported |
26.3% |
Marshmallow |
6.0 - 6.0.1 |
October 5, 2015 |
23 |
Supported |
29.7% |
Nougat |
7.0 - 7.1.2 |
August 22, 2016 |
24 - 25 |
Supported |
23.3% |
Oreo |
8.0 - 8.1 |
August 21, 2017 |
26 - 27 |
Supported |
0.5% |
As mentioned in the preface, the code samples that are bundled with this book support Lollipop (API 21) as their minimum requirement. This is because at the time of this writing, 80% of all Android devices in circulation run a version of Android equal or bigger to Lollipop.
1.3. Android Application Startup
When a user taps on the icon of an Android application a whole series of events happen in the device. Many of these events are very similar to those in iOS, and it turns out that, quite unsurprisingly, both operating systems use a very similar architecture, but with quite different class structures backing them.
Let us create a small project in Android Studio. In that project, add a subclass of the android.app.Application
class, and register that class as the main application class in your AndroidManifest.xml file. Add two breakpoints in the source code, one in the Application.onCreate()
method, and another in the MainActivity.onCreate()
method.
The stack traces when hitting both breakpoints is shown below:
training.akosma.startup.StartupApplication.onCreate(StartupApplication.java:8) com.android.tools.fd.runtime.BootstrapApplication.onCreate(BootstrapApplication.java:370) android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1012) android.app.ActivityThread.handleBindApplication(ActivityThread.java:4553) android.app.ActivityThread.access$1500(ActivityThread.java:151) android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364) android.os.Handler.dispatchMessage(Handler.java:102) android.os.Looper.loop(Looper.java:135) android.app.ActivityThread.main(ActivityThread.java:5254) java.lang.reflect.Method.invoke(Method.java:-1) java.lang.reflect.Method.invoke(Method.java:372) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
training.akosma.startup.MainActivity.onCreate(MainActivity.java:10) android.app.Activity.performCreate(Activity.java:5990) android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278) android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) android.app.ActivityThread.access$800(ActivityThread.java:151) android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) android.os.Handler.dispatchMessage(Handler.java:102) android.os.Looper.loop(Looper.java:135) android.app.ActivityThread.main(ActivityThread.java:5254) java.lang.reflect.Method.invoke(Method.java:-1) java.lang.reflect.Method.invoke(Method.java:372) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
There are several interesting bits of information in the stack traces above. First of all, the android.os.Looper
class, which as the name suggests provides the main run loop of the application. Most GUI toolkits include a similar construction, created at application runtime, holding an event queue and routing events from the operating system to the different activities and components of the application.
Looper == NSRunLoop
For all practical purposes, iOS developers will recognize that the |
If you click on the name of a class in Android Studio while holding down the ⌘ key, the IDE will open the corresponding class file; if you do not have the Android source code available in your local workstation the IDE will simply decompile the code from the local SDK and show a stub implementation of the corresponding class, with most of its methods.
By doing this repeatedly, from both the MainActivity
and the Application
subclass you created previously, you are going to arrive to the android.content.Context
class, which is arguably the most important class in the Android SDK. The Context
class includes many different methods, ranging from file management to database creation to inter-process communication, and it also holds a reference to the underlying Looper
class.
Equivalent in iOS
There is no similar equivalent of |
The diagram "The android.content.Context class" shows a simplified class hierarchy of the Activity
and Application
classes and its relationship with the Looper
class.
1.4. Zygote
One of the biggest problems with any Java Virtual Machine (JVM) is the long startup time. In the case of Android, this problem is even bigger, given the limited resources of many devices in the market. Moreover, since every application has to run its own copy of the JVM to ensure privacy and security through sandboxing, the price to pay would be too steep.
Zygote is the name of a process that Android runs as soon as the operating system stops booting. Its objective is to launch a copy of the Android Runtime (ART), which is Android’s version of the JVM, so that it is ready to use by every application in the system.
As soon as the user taps on the icon of an application to launch it, Android will ask Zygote to "fork" a copy of the JVM process, so that each application runs in its own sandbox, without conflicting with other processes. Zygote also preloads a certain number of libraries and resources that are usually required by most Android applications to run properly. All of this substantially speeds up the launching time of applications.
More about Zygote
If you want to know more about Zygote, this answer in Stack Overflow provides an excellent summary. |
1.5. Android Studio
Android Studio is a free IDE provided by Google to develop Android applications. It replaced the venerable Eclipse Android Developer Tools, historically the first official IDE for Android software development for many years. It was announced for the first time in May 2013 at the Google I/O conference. The first stable release was in December 2014. It is available for Windows, macOS and Linux, and is now considered the official IDE for Android development.
End-of-life of the Eclipse Android Developer Tools
Google has announced in November 2nd, 2016 the official end of support and development of the Eclipse Android Developer Tools, which are completely superceded by Android Studio 2.2. |
Android Studio is powered by IntelliJ IDEA, a popular IDE for Java development for the past 15 years. It has a solid reputation, and is particularly appreciated by its advanced support for refactoring, code generation and project navigation features.
Android Studio is available from the Android Studio website. The current version at the time of this writing is 3.0.1. Android Studio is, by far, the most important piece in the daily workflow of an Android Developer, and includes many different features targeted to simplify the development of Android apps, which like all software development can be quite a complex endeavour sometimes.
Once downloaded and launched, Android Studio will launch a configuration wizard, as shown in Android Studio Setup Wizard – Step 1.
Most developers will choose the standard settings, as shown in image Android Studio Setup Wizard – Step 2.
Finally, Android Studio will automatically download all the elements required for it to work properly, as shown in image Android Studio Setup Wizard – Step 3.