---
title: "Android from a Drupal Perspective"
url: "/articles/android-from-a-drupal-perspective"
type: article
date: 2013-08-07
updated: 2014-05-15
---

# Android from a Drupal Perspective

#  Android from a Drupal Perspective 

 By

 [  Andrew Berry   ](/about/andrew-berry) 

 August 7, 2013

  

Iâ&#128;&#153;ve been spending some time learning Android app development. I was initially attracted to it as I liked the openness of the [various](https://play.google.com/) [Android](https://www.amazon.com/mobile-apps/b?ie=UTF8&amp;node=2350149011) [distribution](https://f-droid.org/) [channels](https://www.nvidia.com/en-us/geforce-now/) compared to the [heavy-handed approach Apple takes with iOS](https://en.wikipedia.org/wiki/Approval_of_iOS_apps#Notable_rejected_apps). While Iâ&#128;&#153;m still relatively new to Android development, Iâ&#128;&#153;ve made a few observations that I thought would be interesting to those in the Drupal community.

# Android â&#128;&#156;forksâ&#128;&#157; standard Java APIs

Android uses [Dalvik](https://sites.google.com/site/io/dalvik-vm-internals), a re-implementation of the standard Java Virtual Machine to run apps and substantial portions of the Android operating system. The [Android SDK](https://developer.android.com/sdk/index.html) includes most of the standard Java APIs, packaged under the `java.*` namespace.

Where things get interesting is where the Android API, packaged under the `android.*` namespace, offers similar or enhanced functionality of the standard Java APIs. For example, Android includes XML utilities under `android.util.xml`. Likewise, Java provides (under the Java Extensions namespace) XML utilities under `javax.xml`. In fact, the Android API offers enhancements or alternatives to many core Java APIs.

This is very similar to how Drupal works, where we have enhancements and alternatives in the `drupal_` functions. Many of the [array](https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_array_merge_deep/7), [file](https://api.drupal.org/api/drupal/includes!file.inc/function/drupal_chmod/7), and [string](https://api.drupal.org/api/drupal/includes!unicode.inc/function/drupal_strlen/7) functions mirror core PHP functionality. Re-implementing language APIs isnâ&#128;&#153;t necessarily a bad thing, especially where the language APIs have critical flaws. However, in both Android and Drupal it adds additional complexity for new developers to learn as they have to research each API alternative and decide what is best for their use case.

# Statically typed, done right

Much of the PHP world is going through a change where the dynamically typed nature of PHP is being directed to semi-typed code. While variables themselves do not have a [declared type](https://www.php.net/manual/en/language.types.type-juggling.php), Drupal (and Symfony) now use [type hinting](https://www.php.net/manual/en/language.oop5.typehinting.php) to enforce parameter types on method calls. Take a look at [ConfigImporter::\_\_construct()](https://drupalcode.org/project/drupal.git/blob/6718550cda5757d511a4f8e541cdaaaaa0f1422d:/core/lib/Drupal/Core/Config/ConfigImporter.php); every method parameter has an explicit type.

This semi-static nature of PHP code limits the effectiveness of static code analysis. Using an IDE like Eclipse shows whatâ&#128;&#153;s possible with a static language like Java. For example, it can detect misassignments in variable or return types as you write them in the code itself. Exceptions tend to be more specific (no `catch(Exception $e)`) while also being easier to detect earlier in the development process as each method must document what exceptions it throws.

[Generics](https://docs.oracle.com/javase/tutorial/java/generics/) in particular solve a pain point of a dynamically-typed language like PHP. Load up any one of your production Drupal sites and check the watchdog log for warnings and notices (assuming they are logged at all). Odds are, a good number of them are from trying to iterate over non-arrays or non-objects, or are the result of a random integer or string being stuck into an array of entities or fields. Java solves this by allowing variables and methods to not just declare that they return a map, but that the map keys and values must be of a specified type. If Drupal 7 was written in Java, the declaration for hook\_menu() might be something like:

```
// We return a map (like a PHP array with named keys) where the keys are strings and they point to a map.
public HashMap<String, HashMap> mymodule_menu() {
  â&#128;¦
}

```

Donâ&#128;&#153;t get me wrong; Iâ&#128;&#153;m not saying that we should abandon dynamically typed languages and that all languages should be a [re-implementation of Java](https://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29). But, as Drupal developers, itâ&#128;&#153;s important we keep an eye on what the rest of the programming world is doing so we donâ&#128;&#153;t find ourselves behind current best practices.

# Dynamic objects, done right

Of course, all of this strictness over types and the preference for explicit getter / setter methods in Java leads to a tonne of boilerplate code. Reflection is possible in Java, but itâ&#128;&#153;s nowhere near as easy as in PHP. We get used to being able to iterate over object properties, or using strings as method names or variables. Being able to use arrays as shorthand for accessing a set of object properties in a loop lets us write common methods in PHP in four or five lines. For example, imagine a scenario where we are loading a node from a remote service where we canâ&#128;&#153;t ensure that the data is complete. Writing this validation in PHP could be very simple:

  ```php

$properties = array(â&#128;&#152;nidâ&#128;&#153;, â&#128;&#152;titleâ&#128;&#153;, â&#128;&#152;authorâ&#128;&#153;);
foreach ($properties as $property) {
  if (!isset($node->{$property} || empty($node->{$property}))) {
    throw new MissingPropertyException(â&#128;&#156;Required $property is not set.â&#128;&#157;);
  }
}
  
```

In Java, odds are youâ&#128;&#153;ll end up inlining each if statement, increasing the possibility of bugs or simple copy-paste errors. Sometimes, itâ&#128;&#153;s easy to look at PHP code like this and focus on how much more opaque it is. But, when it comes down to it, in the real world code like this is just too useful to not miss when using other, stricter languages.

# Stepping into the Database API time machine

Like many mobile and desktop application APIs, Android offers a persistent storage layer backed by [SQLite](https://www.sqlite.org/). As a PHP and web developer, this sounds great! Most skills for database management should apply, even if weâ&#128;&#153;re used to using a feature-rich database like MySQL or Postgres. Unfortunately, Androidâ&#128;&#153;s database APIs and examples seem like a step back to the days when PHP developers used [mysql\_query](https://www.php.net/manual/en/function.mysql-query.php) as the primary method of database interaction.

The first issue youâ&#128;&#153;ll run into when youâ&#128;&#153;re setting up your tables to store data. Unlike Drupal with itâ&#128;&#153;s [Schema API](https://drupal.org/node/146843), Android creates tables by [executing a SQL string](https://developer.android.com/guide/topics/data/data-storage.html#db) manually created in your code. Since itâ&#128;&#153;s Java, string concatenation isnâ&#128;&#153;t nearly as simple as with PHP, leading to code thatâ&#128;&#153;s difficult to read and littered with string constants. While the [android.database.sqlite](https://developer.android.com/reference/android/database/sqlite/package-summary.html) package offers methods for most common database queries, it is missing some functionality that Drupal developers will immediately notice. Most notably is execute [MergeQueries](https://api.drupal.org/api/drupal/includes!database!query.inc/class/MergeQuery/7). Fetching results is done with the [SQLiteCursor](https://developer.android.com/reference/android/database/sqlite/SQLiteCursor.html) class, which is serviceable but doesnâ&#128;&#153;t have some of the convenience methods Drupal developers are used to such as [fetchAll](https://api.drupal.org/api/drupal/includes!database!prefetch.inc/function/DatabaseStatementPrefetch%3A%3AfetchAll/7)().

Androidâ&#128;&#153;s API includes a [SQLiteQueryBuilder](https://developer.android.com/reference/android/database/sqlite/SQLiteQueryBuilder.html#query%28android.database.sqlite.SQLiteDatabase,%20java.lang.String%5B%5D,%20java.lang.String,%20java.lang.String%5B%5D,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String%29) which is great for dynamically constructing SELECT queries. Unfortunately, itâ&#128;&#153;s limited to *only* SELECT queries. Want to dynamically construct an INSERT or UPDATE query? Back to raw manipulation of a query string, just like the dreaded [db\_rewrite\_sql()](https://api.drupal.org/api/drupal/includes!database.inc/function/db_rewrite_sql/6).

Sometimes we like to complain about the abstraction presented by [db\_select()](https://api.drupal.org/api/drupal/includes!database!prefetch.inc/function/DatabaseStatementPrefetch%3A%3AfetchAll/7) and friends. Using Androidâ&#128;&#153;s DB APIs is a great reminder of just how developer friendly Drupal 7â&#128;&#153;s database layer is.

# Gaining Perspective

Itâ&#128;&#153;s been an interesting experience to dig into a completely different language, API, and application paradigm after spending many years focusing on both Drupal and the web in general. Iâ&#128;&#153;m sure there will be more striking similarities and differences I run across as I keep exploring and learning. Have you learned something that made your Drupal-influenced mind shocked (or made your jaw drop) while learning a new language or API? Let us know in the comments!

 Published in:

- [  Drupal Development   ](/topics/drupal-development)

 

   You must have JavaScript enabled to use this form.

## Get in touch with us

### Tell us about your project. We'd love to hear from you!

 First Name  

 Last Name  

 Your email address  

 Your organization  

 How you heard about us  

 Tell us more 

     Leave this field blank