Chris Muir
Chris Muir

Reputation: 445

What's the GoogleApiClient design pattern?

I've been using Android's GoogleApiClient for some time in accessing other APIs like geofencing. I appreciate through the GoogleApiClient and Google Play Services, Google has been trying to tackle the Google fragmentation problem, by allowing older Android devices to download successive updates to the APIs contained within without requiring a whole new operating system update.

What's been unclear to me down at the Java level is why does the GoogleApiClient need to and supports callbacks for connect/suspend/fail? Without further detail it seems the GoogleApiClient which is essentially a wrapper to other APIs is overbaked and overengineered. Couldn't connecting/suspending/etc have been transparent to developers? At worst on a failure to access a service, couldn't it just have thrown an exception?

So rather than criticizing I do think there is a hole in my knowledge which means I can't appreciate the design. Why has Google designed the API client in this way? Is there a design pattern they were following?

Upvotes: 3

Views: 190

Answers (1)

Michael Aaron Safyan
Michael Aaron Safyan

Reputation: 95499

There are a number of reasons for the way it is structured, but first and foremost, is the fact that:

  • The GoogleApiClient code is designed so that you can call it from the Android UI main thread (without explicitly creating an AsyncTask or background thread)
  • The GoogleApiClient code can take a long time to run (e.g. if the user has not installed Play Services, it will prompt the user to download / install Play Services, and only return control back to the application after Play Services has been installed)
  • The Android UI will become unresponsive if the main thread is blocked by long-running operations (such as downloading an application from the Play Store). Consequently, registering callbacks is pretty standard for such code in Android land. [Blocking the Android UI main thread for a long time is a common cause of the system force-quitting an application]

Now, on top of that, one of the many things that adds to Play Services' complexity is the need for flexibility, the need to support many different features / libraries without each and every application that uses Play Services to need to compile / include each and every library it supports (and, related to that, avoiding bloating every single application by having all the functionality of Play Services duplicated in each app that takes advantage of Play Services). For this reason, Play Services uses a client-server architecture; apps that use Play Services don't import all of Play Services (including the code that provides the underlying functionality of that system). Rather, each app that uses Play Services imports a much smaller, more focused set of interfaces that are able to communicate with the implementation of those services in the Play Services app (and only the Play Services app, itself, needs to include all of the logic that actually implements those interfaces). Because of this architecture, though, you need to do the equivalent of "import" but at runtime... that is, you need to possibly download and initialize the Play Services app before using its functionality.

Upvotes: 3

Related Questions