Android Application Development All-in-One For Dummies book cover

Android Application Development All-in-One For Dummies

Authors:
Barry Burd ,
John Paul Mueller
Published: August 4, 2020

Overview

Conquer the world of Android app development 

Android has taken over the mobile and TV markets and become unstoppable! Android offers a vast stage for developers to serve millions—and rake in the profits—with diverse and wide-ranging app ideas. Whether you’re a raw recruit or a veteran programmer, you can get in on the action and become a master of the Android programming universe with the new edition of Android Application Development For Dummies All-in-One. In addition to receiving guidance on mobile and TV development, you’ll find overviews of native code, watch, car, Android wear, and other device development. 

This friendly, easy-to-follow book kicks off by offering a fundamental understanding of Android’s major technical ideas, including functional programming techniques. It moves on to show you how to work effectively in Studio, program cool new features, and test your app to make sure it’s ready to release to a waiting world. You’ll also have an opportunity to brush up on your Kotlin and develop your marketing savvy. There are millions of potential customers out there, and you want to stand out from the crowd!  

  • Understand new features and enhancements 
  • Get development best-practices 
  • Know your Android hardware 
  • Access online materials 

With a market share like Android’s, the stakes couldn’t be higher. Android Application Development For Dummies All-in-One levels the field and gives you the tools you need to take on the world.  

 

Conquer the world of Android app development 

Android has taken over the mobile and TV markets and become unstoppable! Android offers a vast stage for developers to serve millions—and rake in the profits—with diverse and wide-ranging app ideas. Whether you’re a raw recruit or a veteran programmer, you can get in on the action and become a master of the Android programming universe with the new edition of Android Application Development For Dummies All-in-One. In addition to receiving guidance on mobile and TV development, you’ll find overviews of native code, watch, car, Android wear, and other device development. 

This friendly, easy-to-follow book kicks off by offering a fundamental understanding of Android’s major technical ideas, including functional programming techniques. It moves on to show you how to work effectively in Studio, program cool new features, and test your app to make sure it’s ready to release to a waiting world. You’ll also have an opportunity to brush up on your Kotlin and develop your marketing savvy. There are millions of potential customers out there, and you want

to stand out from the crowd!  

  • Understand new features and enhancements 
  • Get development best-practices 
  • Know your Android hardware 
  • Access online materials 

With a market share like Android’s, the stakes couldn’t be higher. Android Application Development For Dummies All-in-One levels the field and gives you the tools you need to take on the world.  

 

Android Application Development For Dummies All-in-One Cheat Sheet

Android development techniques move forward at a near frantic pace with so many different devices to work with and the use of a new language named Kotlin. With each change, the development environment becomes more functional and less error prone with increased reliability. Kotlin reduces the complexity of development, but the addition of platforms and app types increases it. Android development you do today is different from the development you performed even six months ago. Android has become the platform of choice for so many tasks that, after you get up to speed, it will boggle your mind to see how many different ways you can employ it. No matter how you work with Android, this Cheat Sheet will help you perform tasks more effectively. [caption id="attachment_271881" align="alignnone" width="556"] ©senrakawa/Shutterstock.com[/caption]

Articles From The Book

4 results

App Development Articles

Using the Kotlin Function in Your Android App

As an Android app developer, you’ll want to know how to use Kotlin. Kotlin functions provide just what you need. What is a Kotlin function? So glad you asked! You hear multiple terms for a package of code found in an easily callable form. For example, a procedure is a set of operations executed without calculating any return value. When you program with Java, you hear about the method, because methods are associated with objects. Java is focused on objects, so the most appropriate term is method — a method of working with that object in some meaningful way. In Kotlin, you find functions. A function is a set of operations that don’t necessarily link to an object but always return a value. If a Kotlin function doesn’t provide a specific return value, it returns a value called Unit. Consequently, you never use the term procedure when working with Kotlin because the procedure doesn’t exist (although you could make the argument that procedures do exist in Java). Here is an example of the Unit return value:

val result = println("A String")

if (result is Unit) {
    println("result is of type Unit")
    println(result)
}
You wouldn’t expect println() to return a value, and it doesn’t, but it does return Unit. Because println() is a stand-alone call not associated with an object, you always call it a function. A Minimalistic Android Activity Class
package com.example.myfirstapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
Looking at the code above, you see the onCreate() function, which is part of the MainActivity class. Because onCreate() exists as part of a class in this case, you can also call it a method. The onCreate() method exists as a part of objects instantiated from MainActivity. Remember that a function that appears as part of a class is more specifically called a method, even though it’s also a function. Some ambiguity exists in other languages that use the static method, which is part of a class but is not called as part of an object. Some people argue that these methods are really functions. Kotlin gets rid of the ambiguity by using companion objects in place of static methods in classes. The point is that they really are methods in Kotlin because they’re members of the associated singleton object. Kotlin functions have certain characteristics, as shown in the following code:
fun main(args: Array) {
    println(monthlyPayment(10_000.00, 5.25, 30))
    println(monthlyPayment(10_000.00, 5.00, 15))
}

fun monthlyPayment(principle: Double, 
                   percentageRate: Double, 
                   years: Int): Double {
    
    val numPayments: Int = 12 * years
    val rate: Double = percentageRate / 100.00
    val effectiveRate: Double = rate / 12
    
    return (principle * effectiveRate / 
           (1 - Math.pow(1 + effectiveRate, 
                         -numPayments.toDouble())))
When you run this example, you receive the expected monthly payments given a 10,000 loan, certain percentage rates, and the number of years that someone will make payments. The functions used in this example have certain characteristics:
  • The names of the two functions are main() and monthlyPayment().
  • In the body of the monthlyPayment() function declaration, the processor computes the monthly payments on a mortgage. You can follow this description of functions and function parameters without understanding anything about the calculations.
  • The body of the monthlyPayment() function uses certain names as placeholders. For example, in the body of the monthlyPayment() function, the name years stands for the number of years in the mortgage's term. Likewise, the name principal stands for the total amount borrowed.
  • Some placeholders appear in parentheses at the beginning of the function’s declaration. The names principal, percentageRate, and years are the function’s parameters. Each parameter is destined to stand for a particular value. But a parameter doesn't stand for a value until an app executes a function call.

The main() function contains a call to monthlyPayment(10_0000.00, 5.25, 30) that gives the function’s first parameter (namely, principal) the value 10000.00. That same call gives the function’s second parameter (percentageRate) the value 5.25. Finally, that function call gives the method's third parameter (years) the value 30.

The next function call in main() gives the monthlyPayment() function’s parameters different values (again 10000.00 for principal, but 5.00 for percentageRate and 15 for years). Each time you call a function, you supply values for the function’s parameters.

  • The types of parameters in a function call must match the types of the parameters in a function declaration. The declaration of function monthlyPayment() has a Double parameter (principal), another Double parameter (percentageRate), and an Int parameter (years). Accordingly, the first function call has two Double parameters (10000.00 and 5.25) followed by an Int parameter (30). The second function call also has two Double parameters followed by an Int parameter.

You can declare the same function more than once, as long as each declaration has a different parameter list. For example, another monthlyPayment() function declaration might have the same name monthlyPayment but only two parameters: principle: Double and percentageRate: Double. To call this alternative monthlyPayment() function, you write something like monthlyPayment(10_000.00, 5.00). In this situation, the body of the alternative monthlyPayment() method probably contains a statement like val years: Int = 30. You don't call this two-parameter method unless you know that the mortgage's term is 30 years.

  • A function call might stand for a value. The first function call in main() stands for the Double value 55.22 (or a value very close to the number 55.22). The value 55.22 comes from all the calculations in the body of the monthlyPayment() function when the principal is 10000.00, the percentageRate is 5.25, and the number of years is 30. Near the end of the monthlyPayment() function body, the formula
principle * effectiveRate / 
(1 - Math.pow(1 + effectiveRate, 
              -numPayments.toDouble()))

has the value 55.22, and the word return says “send 55.22 back to the statement that called this method.” So, the end of the monthlyPayment() function body effectively says

return 55.22

and the associated println() statement in main() effectively says

println(55.22)

Similarly, the second println() function call in main() outputs the value 79.08. Because of the second function call's parameter values, the end of the monthlyPayment() function body effectively says

return 79.08

and the last line in the listing effectively says

println(79.08)

A function’s declaration can end with the name of the return type. The monthlyPayment() function declaration begins with the keyword fun (which is short for function), followed by the function name, monthlyPayment, a list of parameters in parentheses, and finally the keyword Double. That's good because the value returned at the end of the method's body (either 55.22 or 79.08) is of type Double.

Want to learn more? Find out why Kotlin is the best choice for developing your Android app.

App Development Articles

Why Kotlin Is Great For Android App Development

There aren’t any perfect programming languages. However, Google has decided that Kotlin is as close as it gets when it comes to developing Android apps. Having said that, Java lovers can still use their favorite language to make their Android apps. Part of the problem is that no one can agree on what constitutes perfect. People like to fight about things, including programming language features. With this in mind, you might feel sorry for Java as the victim of mean-spirited finger pointing by those who just don’t like the language. However, as you’ll soon discover, Java has some real issues that Kotlin attempts to fix. Whether you agree with the fixes is a matter for you to decide, of course.

Kotlin improves control over null references

A null reference describes an object that points to nothing. It’s sort of like having a mailbox on a post outside of an empty lot. Yep, there is a mailbox there, but no one will ever get the mail. The mailbox, the object, seems to point to something, but when you investigate it, you find that it doesn’t point to anything at all —the lot is empty. When you try to access an object that points to null in Java, you get the dreaded NullPointerException. Of course, the first thing on your mind is determining what happened to the house that’s supposed to appear on that empty lot. Unfortunately, we’ve been dealing with the null reference since 1965, when Tony Hoare decided to add it to ALGOL W. He calls it his billion-dollar mistake during the 2009 QCon London presentation. When the inventor of a method of doing something says it was a horrid mistake, getting rid of it seems like a good idea. But getting rid of the null reference would mean breaking a lot of Java code, so that’s where Kotlin comes into play. Kotlin doesn’t actually remove null references entirely, but it does help you control them better. For example, the following code results in a compilation error in Kotlin:
var a: String = "abc"
a = null
println(a)
A String is a non-nullable type. The type system ensures that you can’t place a null value in a for any reason. Consequently, a can never experience a NullPointerException. Of course, there must be allowances. You can tell Kotlin to allow null values in specific cases by using a special operator. The following code defines a nullable String and will compile:
var a: String? = "abc"
a = null
println(a)
However, when you print a, what you see is the value null, not a NullPointerException. Consequently, the null value is still safe. However, it comes with limits. For example, when using the following code, you get an output value of 3.
val a: String = "abc"
println(a.length)
The limitation comes when you make String nullable. The following code produces a compilation error saying that only safe calls are allowed on nullable String objects.
val a: String? = "abc"
println(a.length)
You still might want to check the length of a. Kotlin has a workaround for this issue as well. The following code first determines whether a is null and, if it isn’t, returns length:
val a: String? = "abc"
println(a?.length)
What if you want to assign a potentially null value to another variable? In this case, you rely on the Elvis operator (?:). The following code safely assigns that length of a to b, unless a is null, in which case, b receives a value of 0:
val a: String? = "abc"
val b = a?.length ?: 0
println(b)
It seems that Kotlin is quite determined not to allow you to produce a NullPointerException in your code. If you’re equally determined to produce one, you can use the not-null assertion operator (!!), as shown in the following code:
val a: String? = null
println(a!!.length)
Kotlin goes only so far to protect you from yourself. You can still see a NullPointerException in these situations:
  • The throw NullPointerException() being specifically called by the code.
  • The use of the non-null assertion operator (!!), described earlier.
  • A data inconsistency that results from improper initialization:
  • Your code calling Java code that produces a NullPointerException. Unfortunately, Kotlin can’t protect you from Java.

Kotlin removes raw data types

A raw data type occurs when you create a generic Java type without specifying a data type as part of the declaration. For example, here is a raw data type in Java:
List names = Arrays.asList("John", "Mia", "Herb", "Ann");
This code will compile in Java. The problem with this code is that you have no idea what data type names contains; it could be anything. More important, the compiler now has to guess what data type to use, and forcing the compiler to guess is always a bad idea. Plus, to use the values in names, you must now cast the individual entries, such as
Iterator iter = stars.iterator();
while(iter.hasNext()) {
  String name = (String) iter.next(); //cast needed
  println(name);
}
Kotlin can use Java types. In fact, you can interoperate with Java successfully using certain techniques. However, to use names in Kotlin, you must specifically declare a type, as shown here:
val names: List = 
   Arrays.asList("John", "Mia", "Herb", "Ann")

for (name in names){
    println(name)
}
Notice that using Java types in Kotlin is a little different from how you use them in Java. However, the basic principle is the same. You define names as type List and then assign it names using Arrays.asList("John", "Mia", "Herb", "Ann"). The point is that you can’t use raw data types because the compiler will display an error.

Kotlin uses invariant arrays

When working with Java, you can copy an array of a specific type, such as String, to an array of type Object. You can then manipulate the items in the Object array as desired. Consequently, code like this will compile without problem in Java:
String[] stuff = {"Tom", "Sam", "Ann"};
Object[] moreStuff = stuff;
You can do things this way because arrays are covariant in Java. String is subclassed from Object, so an Object can contain a String. However, when you’re able to do things like this, you can encounter problems. Consider the following code:
String a = stuff[0];
System.out.println(a);
String b = moreStuff[0];
System.out.println(b);
This code won’t compile because Java loses track of the type of the data in moreStuff. It now views element 0 as an Object, not a String, so it can’t make the second assignment to b. Of course, you can overcome this issue by using a cast: String b = (String)moreStuff[0];. However, now that you’ve fixed one problem, you have another. Look at this code:
String a = stuff[0];
System.out.println(a);
moreStuff[0] = 5;
String b = (String)moreStuff[0];
System.out.println(b);
You now get a runtime error because you can’t cast an Integer (the changed type of moreStuff[0]) to a String. Java overcomes this problem by using generics, which are invariant (objects must be of the same type when you set one equal to the other). This code won’t compile because converting a String to an Object isn’t possible.
List stuff = Arrays.asList("Tom", "Sam", "Ann");
List moreStuff = stuff;
Generics are invariant in Java. Likewise, arrays are invariant in Kotlin. Consequently, this Kotlin code won’t compile for the same reason that generics won’t compile in Java:
val stuff: Array = arrayOf("Tom", "Sam", "Ann")
val moreStuff: Array = stuff

Kotlin lets you work with proper function types

The term proper function types refers to the kind of programming performed using lambda functions in a functional programming way. Most Java developers aren’t really familiar with functional programming because functional programming is historically difficult to implement in Java, and addressing all the tenets of functional programming isn’t possible. However, Java developers can perform functional programming after a fashion by using techniques such as Single Abstract Method (SAM) conversions. To give you some idea of how functional programming differs from Java programming, here are the basic tenets:
  • Creating functions that are first-class objects
  • Using pure functions
  • Employing higher-order functions
  • Relying on a lack of function state
  • Depending on an absence of side effects
  • Using immutable variables
  • Favoring recursion over looping
As you can see, trying to implement most of these requirements in Java would be impossible, or at least nearly so. However, this article demonstrates that some of them are possible and that there are distinct benefits to using this functional programming approach. For example, here’s an example of a Java pure function:
public class performSum{

    public int sum(int a, int b) {
        return a + b;
    }
}
The function doesn’t have state, it doesn’t use any sort of member variables, and it relies only on the input variables. Because of this, you can be sure that every call to this function with a given set of inputs will have precisely the same result every time. Java’s lambda functionality relies on SAM, which is an interface version (also called a functional interface) of the pure function. Here’s an example of SAM:
public interface OnClickListener {
    void onClick(View v);
}
A SAM conversion occurs when Java converts the SAM interface into functional code. Here is the lambda expression for the SAM interface:
myView.setOnClickListener((view) -> logger.debug(
    "View Clicked!"));
Unlike Java, Kotlin provides first-class support for lambda functions. You don’t have to create an interface specification in Kotlin to achieve the desired result — all you need is a signature specification provided as part of your function. Consequently, the Kotlin version of the Java example looks like this:
fun setOnClickListener(listener: (view: View) -> Unit) {
   // ...
}
Notice that the listener is defined as part of the function signature. The signature defines the callable parameters and the resulting output. More important, a callable parameter can be just about anything, including a function. This is an extremely quick overview of a more complex process.

The main issue to consider when working with the Kotlin form of lambda expressions is that the Kotlin form is essentially incompatible with the Java form, making interop a lot more difficult to deal with. You can use the Java form of lambda expressions in Kotlin when working with Java code. However, when working with Kotlin code, you must use the Kotlin form instead, which means that you now have to know two ways of making lambda expressions work.

Kotlin gets rid of the checked exceptions

Checked exceptions may have seemed like a good idea at first because the developer is forced to ensure that code using particular methods also checks for exceptions that can occur as a result of relying on that method. Over the years, however, developers have found that checked exceptions don’t necessarily create robust code and that they do waste of a lot of time. Here are some resources to consider: The point of these articles is that checked exceptions were an experiment that didn’t work. Languages that follow the Java example don’t use them for a good reason. When you look at C# and Ruby, you don’t see checked exceptions, so it’s hardly a surprise that Kotlin eliminates them, too. Want to learn more? Check out this article discussing Kotlin.

App Development Articles

Android App Developer Tools

Android is a multifaceted beast. When you develop for Android, you use many tool sets. This article gives you a brief rundown of the tools you can use to develop Android apps.

Java and Kotlin for Android app development

James Gosling from Sun Microsystems created the Java programming language in the mid-1990s. (Sun Microsystems has since been bought out by Oracle.) Java's meteoric rise in use came from the elegance of the language and the well-conceived platform architecture. After a brief blaze of glory with applets and the web, Java settled into being a solid, general-purpose language with special strength in servers and middleware. In the meantime, Java was quietly seeping into embedded processors.

An embedded processor is a computer chip that's hidden from the user as part of some special-purpose device. The chips in today's cars are embedded processors, and the silicon that powers your photocopier at work is an embedded processor. Pretty soon, the flowerpots on your windowsill will probably have embedded processors. By 2002, Sun Microsystems was developing Java ME (Mobile Edition) for creating MIDlets based on the Mobile Information Device Profile (MIDP) to run on mobile phones in a manner similar to applets on a web page. Java became a major technology in Blu-ray disc players, parking meters, teller machines, and other devices. So, the decision to make Java the primary development language for Android apps was no big surprise.

The trouble was, not everyone agreed about the fine points of Java's licensing terms. The Java language isn't quite the same animal as the Java software libraries, which in turn aren't the same as the Java Virtual Machine (the software that enables the running of Java programs). So, in marrying Java to Android, the founders of Android added an extra puzzle piece — the Dalvik Virtual Machine. And instead of using the official Sun/Oracle Java libraries, Android used Harmony — an open-source Java implementation from the Apache Software Foundation. Several years and many lawsuits later, Google and Oracle were still at odds over the use of Java in Android phones. Programmers always use one kind of software to develop other kinds of software. For several years, programmers had developed Android apps using software named Eclipse. In the meantime, a competing product named IntelliJ IDEA was growing in popularity. A group of engineers from Google and IntelliJ IDEA's parent company (JetBrains) cooperated to create a very lean version of IntelliJ IDEA. Simply put, they removed the features of IntelliJ IDEA that Android developers would never use. From this stripped-down version of IntelliJ IDEA, they created a customized product especially for Android programmers. At its annual developer conference in 2013, Google introduced Android Studio — the shiny new tool to help Android developers be more productive. Also at the aforementioned 2013 developer conference, Google began the process of replacing Dalvik with a new virtual machine named Android Runtime, or ART. Programs ran faster under ART, plus they consumed less memory and less power, and they were easier to debug. The transition from Dalvik to ART was a first step in the separation of Android from Oracle's proprietary Java technologies. While Android matured, new programming languages were making improvements on many of Java's long-standing features. Apple was developing Swift to replace the aging Objective-C language. With Swift and other such languages, developers had a natural way of controlling how values may change during the run of a program. Developers could easily extend existing functionality and create code to tame null values — values that expert Tony Hoare had dubbed a "billion-dollar mistake." In newer languages, programmers used built-in features to write code in a functional style (a coding technique that expresses computational goals in the form of math functions). JetBrains was developing one of these new languages. The language's name — Kotlin — came from the name of an island near St. Petersburg in Russia. Kotlin borrowed many of Java's features and improved on them in significant ways. At its annual developer conference in 2017, Google announced support for creating Android programs using Kotlin. A year later, 35 percent of all Android programmers were using Kotlin. In 2019, Google officially dubbed Kotlin as the preferred language for Android app development. Kotlin is fully compatible with Java. So, when you create an Android app, you can borrow pieces of programs written in Java and meld them seamlessly with your Kotlin code. Kotlin also integrates with JavaScript, so developers can write Kotlin programs that drive web pages.

Behind the scenes, Kotlin plays nicely with Node.js — a widely-used platform that runs on servers around the world. You can even translate Kotlin into native code — code that runs on Windows, macOS, Linux, and other operating systems.

Kotlin is deeply entrenched in the Android ecosystem and in other systems as well. If you already have some Kotlin programming experience, great! If not, there are plenty of resources to help you broaden your horizons into Kotlin programming.

XML for Android app development

If you find View Source among your web browser's options, you see a bunch of Hypertext Markup Language (HTML) tags that represent the coding for a web page. A tag is some text enclosed in angle brackets. The tag describes something about its neighboring content. For example, to create boldface type on a web page, a web designer writes Look at this! The angle-bracketed b tags turn boldface type on and off. The M in HTML stands for Markup — a general term describing any extra text that annotates a document's content. When you annotate a document's content, you embed information about the document's content into the document itself. So, for example, in the line of code in the previous paragraph, the content is Look at this! The markup (information about the content) consists of the tags and . The HTML standard is an outgrowth of SGML (Standard Generalized Markup Language). SGML is an all-things-to-all-people technology for marking up documents for use by all kinds of computers running all kinds of software and sold by all kinds of vendors. In the mid-1990s, a working group of the World Wide Web Consortium (W3C) began developing XML — the eXtensible Markup Language. The working group's goal was to create a subset of SGML for use in transmitting data over the Internet. The group succeeded. Today, XML is a well-established standard for encoding information of all kinds. Java is good for describing step-by-step instructions, and XML is good for describing the way things are (or should be). A Java program says, “Do this and then do that.” In contrast, an XML document says, “It's this way, and it's that way.” Android uses XML for two purposes:
  • To describe an app's data. An app's XML documents describe the look of the app's screens, the translations of the app into one or more languages, and other kinds of data.
  • To describe the app itself. Each Android app comes with an xml file. This XML document describes features of the app. The operating system uses the AndroidManifest.xml document's contents to manage the running of the app.
For example, an app's AndroidManifest.xml file contains the app’s name and the name of the file containing the app’s icon. The XML file also lists the names of the app’s screens and tells the system what kinds of work each screen can perform. For more information about the AndroidManifest.xml file and about the use of XML to describe an app's data. Concerning XML, there's bad news and good news. The bad news is, XML isn't always easy to compose. The good news is, automated software tools compose most of the world's XML code. The software on an Android programmer’s development computer composes much of an app's XML code. You often tweak the XML code, read part of the code for info from its source, make minor changes, and compose brief additions. But you hardly ever create XML documents from scratch.

When you create an Android app, you deal with at least two “computers.” Your development computer is the computer that you use for creating Android code. (In most cases, your development computer is a desktop or laptop computer — a PC, Mac, or Linux computer.) The other computer is something that most people don't even call a “computer.” It's the Android device that will eventually be running your app. This device is a smartphone, tablet, watch, or some other cool gadget.

Linux for Android app development

An operating system is a big program that manages the overall running of a computer or device. Most operating systems are built in layers. An operating system's outer layers, such as the applications and the environment in which the user interacts with the applications, are usually right up there in the user's face. For example, both Windows and macOS have standard desktops (a paradigm for the interface the user sees, sort of like the physical desktop you use at work). From the desktop, the user launches programs, manages windows, and so on. When you’re working with Android, the desktop is represented by the Android Application Framework. An operating system's inner layers are (for the most part) invisible to the user. While the user plays Solitaire, the operating system juggles processes, manages files, keeps an eye on security, and generally does the kinds of things that the user shouldn't micromanage. The image below shows the Android version of these inner layers as Libraries and the Android Runtime. At the very deepest level of an operating system is the system's kernel. The kernel runs directly on the processor's hardware and does the low-level work required to make the processor run. In a truly layered system, higher layers accomplish work by making calls to lower layers. So an app with a specific hardware request sends the request (directly or indirectly) through the kernel. The best-known, best-loved general-purpose operating systems are Microsoft Windows, Apple macOS (which is built on top of UNIX), and Linux (from various vendors). Windows and macOS are the properties of their respective companies. But Linux is open source. That's one of the reasons why the creators of Android based their platform on the Linux kernel. Openness is a good thing!

Rules concerning the use of open-source software come in many shapes and sizes. For example, there's the GNU General Public License (GPL), the Apache License, the GNU Lesser General Public License (LGPL), and others. When considering the use of other people's open-source software, be careful to check the software's licensing terms. “Open source” doesn't necessarily mean “do anything at all for free with this software.”

Here's a ten-cent tour of the Android operating system:
  • first, you have the applications — the web browser, the contacts list, the games, the dialer, the camera app, and other goodies. Developers and users interact with this layer. Developers write code to run on this layer, and users see the screens created by apps in this layer.
  • Below the applications layer lies the Application Programming Interface (API) layer. Your Android programs make requests to pieces of code in this API layer.As an Android developer, you almost never deal with layers below the API layer. But just this once, you can take a quick peek at those three layers. Here goes . . .
    • Android's middle layer has two parts: a bunch of code written in the C and C++ programming languages; and the Android Runtime (ART). The Android Runtime is a workhorse that runs all your Kotlin code.
    • The Hardware Abstraction Layer (HAL) is a kind of universal translator. Imagine having guests from many foreign countries and speaking none of their languages. You can learn all their languages, but hiring several translators is easier. That's how HAL works. The Android Runtime runs on many different kinds of hardware, but ART isn't tailored for any particular kind of hardware. Instead, ART hires a HAL for each kind of hardware. Pretty clever!
    • At the bottom is the Linux kernel, managing various parts of a device's hardware. The kernel includes a Binder, which handles all communication among running processes. When your app asks, “Can any software on this phone tell me the current temperature in Cleveland, Ohio?” the request for information goes through the kernel's Binder.
As an Android app developer, your most intimate contact with the Android operating system is through the command line, or the Linux shell. The Linux shell uses commands, such as cd to change to a directory, ls to list a directory's files and subdirectories, rm to delete files, and many others. The Google Play Store has plenty of free terminal apps. A terminal app's interface is a plain text screen in which you type Linux shell commands. And with one of Android's developer tools, the Android Debug Bridge, you can issue shell commands to an Android device through your development computer. If you like getting your virtual hands dirty, the Linux shell is for you. Want to learn more? Check out our Android App Development Cheat Sheet.