Android from a Drupal Perspective

I’ve been spending some time learning Android app development. I was initially attracted to it as I liked the openness of the various Android distribution channels compared to the heavy-handed approach Apple takes with iOS. While I’m still relatively new to Android development, I’ve made a few observations that I thought would be interesting to those in the Drupal community.

Android “forks” standard Java APIs

Android uses Dalvik, a re-implementation of the standard Java Virtual Machine to run apps and substantial portions of the Android operating system. The Android SDK 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, file, and string functions mirror core PHP functionality. Re-implementing language APIs isn’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, Drupal (and Symfony) now use type hinting to enforce parameter types on method calls. Take a look at ConfigImporter::__construct(); 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’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 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() {
  …
}

Don’t get me wrong; I’m not saying that we should abandon dynamically typed languages and that all languages should be a re-implementation of Java. But, as Drupal developers, it’s important we keep an eye on what the rest of the programming world is doing so we don’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’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’t ensure that the data is complete. Writing this validation in PHP could be very simple:

  
$properties = array(‘nid’, ‘title’, ‘author’);
foreach ($properties as $property) {
  if (!isset($node->{$property} || empty($node->{$property}))) {
    throw new MissingPropertyException(“Required $property is not set.”);
  }
}
  

In Java, odds are you’ll end up inlining each if statement, increasing the possibility of bugs or simple copy-paste errors. Sometimes, it’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. As a PHP and web developer, this sounds great! Most skills for database management should apply, even if we’re used to using a feature-rich database like MySQL or Postgres. Unfortunately, Android’s database APIs and examples seem like a step back to the days when PHP developers used mysql_query as the primary method of database interaction.

The first issue you’ll run into when you’re setting up your tables to store data. Unlike Drupal with it’s Schema API, Android creates tables by executing a SQL string manually created in your code. Since it’s Java, string concatenation isn’t nearly as simple as with PHP, leading to code that’s difficult to read and littered with string constants. While the android.database.sqlite package offers methods for most common database queries, it is missing some functionality that Drupal developers will immediately notice. Most notably is execute MergeQueries. Fetching results is done with the SQLiteCursor class, which is serviceable but doesn’t have some of the convenience methods Drupal developers are used to such as fetchAll().

Android’s API includes a SQLiteQueryBuilder which is great for dynamically constructing SELECT queries. Unfortunately, it’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().

Sometimes we like to complain about the abstraction presented by db_select() and friends. Using Android’s DB APIs is a great reminder of just how developer friendly Drupal 7’s database layer is.

Gaining Perspective

It’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’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:

Get in touch with us

Tell us about your project or drop us a line. We'd love to hear from you!