Futures support and breaking changes in the Mobile Services Android SDK

We’ve released a major update in the Android SDK for Azure Mobile Services. Addressing some feedback about the usage of asynchronous calls in Android, we added support for Futures in all of the asynchronous operations so that you can easily perform multiple of those operations (while on a background thread) without having to deal with multiple nested callbacks. The changes are additive (new methods which return futures in side by side with the ones which take a callback parameter) in most of the scenarios, but in some fundamental interfaces used in more advanced ones (such as the ServiceFilter) we made a breaking change so that futures is now the default model used by the Mobile Services Android SDK for dealing with asynchronous operations. In this release we also added offline support, but to focus on the breaking changes I’ll talk about that in an upcoming post. TL;DR: the rest of this post talks about the new futures support and the list of breaking changes; if all you want is the new SDK to play with it, you can get it at http://aka.ms/Iajk6q. Notice that it’s still an alpha version and subject to change.

Futures

Here’s an example of a code which is made simpler by the usage of the new futures support. Before, if we needed to execute multiple operations, the nesting of the callbacks could quickly become a burden. For example, if you need to iterate through the result of a query and update the items, the callback-based code can quickly become non-trivial:

With the futures support, if the code is running a background thread, the calls are much cleaner. Take the code below, which does the same thing as the one above. It’s boils down to 6 lines of code (with some exception handling and thread skipping sprinkled, which would not be necessary if the code was already not in the UI thread, or if it didn’t need to modify a UI component).

That’s the main advantage of using futures: simple programming model (especially regarding chaining futures). But it also gives you other features, such as cancellation, ease of merging (join) multiple futures, among others.

New APIs

Ok, futures are great, how to I use it? For the main operations – table and custom APIs, each method that previously took a callback parameter has a new overload – which doesn’t take the callback but returns a future interface instead. To minimize the changes needed for existing apps the current callback-based methods are still there, but they’re now marked as @deprecated so that they may be removed in a future release (with a major version upgrade). This applies to custom APIs (e.g., before there were 9 overloads of the invokeApi method of the MobileServiceClient class, there are now 18), push registration / unregistration, typed and untyped tables (all CRUD operations) and login (all overloads). For example, those are the old overloads of the invokeApi method:

Breaking changes

When moving to the futures-only / callback-less model, we could maintain backward compatibility in major classes by deprecating the existing methods and adding new methods with the Futures result – and that’s what we did. There are some interfaces which were callback-based, however, and we couldn’t add the futures methods to that interface (as it would break any class which implemented it). We could have duplicated all of the interfaces and made the class implement both the new and the old ones, but that would have caused an unnecessary bloat in the packages. And since we’re moving on the direction of the futures-based code, we decided to go ahead and introduce a breaking change for those interfaces, which is why the new release contains a major version increase. And since we’ve crossed the high threshold for breaking changes, we used the opportunity to do some cleanup in our code, including splitting the (rather large) com.microsoft.windowsazure.mobileservices package into multiple “sub-packages” so that the classes are better organized. Finally, we also changed the query result so that there’s less code to be written. Let’s walk through all breaking changes, and how they can be addressed in your code.

Renamed to Query, with two new subclasses: ExecutableQuery<E> and ExecutableJsonQuery

MobileServiceQueryOperations

Class with the static operations used for creating typed queries. Renamed to QueryOperations.

QueryOrder

There were lots of package changes, but they can be addressed automatically in Eclipse: on the “Source” menu, select “Organize Imports” (or Ctrl+Shift+O)

MobileServiceQuery

The MobileServiceQuery interface was used to represent a query to a table, and it was a generic class typed to the parameter ‘E’. But it was used for both typed (serialization) and untyped (JSON) scenarios, which went against the pattern used in the rest of the SDK. The type of the query object is now ExecutableQuery<E> for the typed case, and ExecutableJsonQuery for the untyped one. Notice that if you don’t store the query object in a variable, the code doesn’t need to be updated. Take the code below which works on the existing (1.1.6) version of the SDK:

One more change above: the method onCompleted of the TableJsonQueryCallback interface used to have a ‘count’ parameter, but its value was never populated (if it was used it was incorrect). We now removed this parameter to better align the Android API with with the managed code.

Service filters

As I mentioned before, service filters are used internally and in advanced scenarios, and we changed them from a callback-based to a futures-based definition. As such, the methods ServiceFilter.handleRequest and NextServiceFilterCallback.onNext now return a ListableFuture instead of taking a callback parameter. Aside from this change, their behavior is the same. For example, here’s the “identity” service filter, one which passes the message through the next filter in the pipeline:

As I mentioned, only advanced users will need to work with filters, so it’s possible that you won’t need to worry about this change.

Wrapping up

Addressing feedback which we received on our SDK, we’ve added futures support for our Android SDK. There were some breaking changes which we listed above, so we’re releasing the SDK in an alpha version so that we can address any additional comments / suggestions / complaints before we release it broadly. Later this week I’ll write about the offline support which we added, so that the Android SDK is now on par with the managed and iOS versions of the SDK. Please try it out, by downloading the SDK at http://aka.ms/Iajk6q, and send us feedback either as comments in this post or in our MSDN forums.