I went to Droidcon last month!
caldo (remember this!)
Droidcon 2017 in Torino, Italy
Here’s the blitz: the speakers hailed from all around Europe, most commonly Germany, Spain, France, Britain, and, of course, Italy. There was a good number of speakers who came from San Francisco: Gradle, Uber, Pinterest, and Google. The Google speakers encouraged devs to write for Google Home and the Google Assistant on Pixel devices, and IoT was a recurring theme throughout the conference and the hackathon. Many of the talks were how-to’s. Some talks were on the soft side and/or politics of being an Android dev, such as the trek to adopting Kotlin in a large team, and resisting being underfunded and second to iOS in priority when it comes to designs and launch dates.
I’ll highlight my favorite talks, and give you some pointers on talks which are specific how-to’s for you to “watch while you do”, per se.
Gradle 3.0 and beyond for Android Development
One of the most exciting talks was the update on Gradle 3.0. Etienne Studder from Gradle talked about three main points in the recent release, which has a myriad of performance improvements.
- Reusing output files from previous builds
- It makes sense to only produce new outputs for the inputs of the gradle tasks that have changed.
- Often times, though, multiple entities (e.g. the CI server, your machine two branch-switches ago, the machines of your teammates) generate the exact same build outputs. Gradle 3.5 and later has a build cache which maps these same inputs to the same outputs, making them available locally and remotely (currently the latter two are separate, there are plans to unify them)
- Worker API
- 3.4 and later - you can offload tasks to the worker API, which will run in a parallel safe way.
- Gradle daemon
- Finally marked as “stable” in 3.0. Reminder, this is a daemon that will run the build work in its own process, in its own JVM. It takes advantage of lots of caching and avoids much bootstrapping overhead.
- Composite builds
- Combining multiple projects into one build. A good example is an application which uses an external library. Combining the codebases in one composite build allows the application to use a local version of the library for debugging purposes.
- Kotlin (coming up)
- You’ll be able to write build scripts in Kotlin soon (fall, at the latest)
- Build scans
- Share all the environment and other context information surrounding a build with your colleagues by just sending them a link!
How do I background? Keeping services in check
Wojtek Kaliciński from Google spoke about the upcoming changes in Android O regarding implicit broadcasts and background services.
Specifically, as was announced in March, many events that apps subscribe to implicitly, with
android.net.conn.CONNECTIVITY_CHANGE being a notorious example, will no longer wake up the apps that are subscribed to them. New restrictions, detailed on the developer pages, will be imposed on how apps can run background tasks. Here, I will focus on some useful tools to help developers migrate their apps, which were mentioned at the talk.
One suggestion Wojtek gave for background jobs that need to be done when a certain event is broadcasted was to use the
onReceive() to perform very quick, main-thread-worthy operations, or to defer longer tasks to a later time. If disk access or other longer operations need to happen, you can
goAsync() to use a 10 second window for any urgent jobs.
Ultimately, apps compliant with Android Nougat and O should use the
JobScheduler so that the system can pick the best time for background tasks to run. Wojtek noted that previously Google had recommended multiple different approaches, some provided by the Android OS, some by Google Play Services, some by the application. He dove into a retrospective of how the different tools came out, starting with AlarmManager which was used by most apps created before 2014. AlarmManager is not exactly designed or named as the main background job manager of the OS, and its incorrect usage often led to battery drain.
JobScheduler, which came out with Lollipop, made it much easier to be a good citizen and let the system pick the optimal times to wake the device.
For a time in 2016,
GcmNetworkManager was Google’s main recommendation for scheduling batched background tasks.
GcmNetworkManager comes as part of Google Play Services, and actually uses
JobScheduler to save battery on devices on Lollipop and higher. Its main appeal over
JobScheduler alone is its backwards compatibility. Now, Wojtek recommends using
JobScheduler on its own for new apps. I wager one good reason for that is the design flaw of depending on Play Services, e.g. Google Play Services updates cause the app’s scheduled tasks to be forgotten.
The most recent development for scheduling background tasks is the Firebase JobDispatcher, which builds upon
GcmNetworkManager and currently behaves almost exactly the same. The intention is to provide a more abstract wrapper allowing the developer to choose whether they want to use
JobScheduler or even (future) Grand Central Dispatch on iOS. Again, for the time being the recommendation seemed to steer toward
JobScheduler if your app will be targeting L+.
Finally, I’ll pass on some tips that Wojtek gave during the talk for migrating your application to O:
- Apps with targetSdkVersion “O” must update Play Services SDK (GcmTaskService now uses onBind())
- JobScheduler and GCM-NM/Firebase JD have different periodic job constraint semantics (Soft (JobSheduler), vs hard (GCM & FJD)
- Prior to O, foreground services had to be started as background services via
Context.startService()and promoted to foreground services via
Service.startForeground(). The developer preview for O contains a method for starting foreground services directly (
NotificationManager.startServiceInForeground(), which was already being deprecated at the time of the talk. In developer preview 2, the API will change to Context.startForegroundService() which will give you a 5 second window of foreground activity* after which you will have to promote your service with Service.startForeground().
- For debugging purposes when you are performing your migration, some useful adb commands are:
am make-uid-idle [--user <USER_ID>] | all | current] <PACKAGE> // make app background immediately
cmd deviceidle tempwhitelist [-u USER] [-d DURATION] [package ..] // put app on temporary whitelist
appops set <package-name> RUN_IN_BACKGROUND deny // enforce background limits on pre-O apps
appops set <package-name> RUN_IN_BACKGROUND allow // don’t enforce background limits on pre-O apps
Finally, some exercises for the reader:
Here are some talks that turned out to be cool things to try at home, or just ponder:
- Kotlin: A Followup by Christina Lee - on adopting Kotlin in a large and diverse Android team, including some politics and practical tips
- Making the most of your Gradle Builds by Egor Andreevici - some great tips on speeding up your builds
- What’s NNNNNNNNew in Android Security? by Scott Alexander was targeted at all Android developers on how to adapt to the changes in Nougat, and to develop defensively (as opposed to focusing on the security design decisions, OS internals, etc.)
- Many talks on Google Assistant and IoT-related topics: Working with Google Assistant, Android Things for IoT Talk, Smart-Watches as paradigm-shifting player in IoT.
- A recommendation for those using RxJava RxJava 2 for the rest of us - some advanced tips and gotchas
- One of my favorites: How to reactively load and cache data without even trying - the New York Times Android team built a great library for loading data into your app. You can plug in your favorite persister, caching policy, and “fetcher”, i.e. the library you want to use for fetching data over the network. Great for your personal projects!
The incredibly italian view from my Airbnb in Torino
Museo dell'automobile - did you know FIAT means Fabbrica Italiana Automobili Torino? Ferrero was born in Torino’s region, too!
The (copy of) the Shroud of Torino - the original gets shown to the public once every 5 years or so.
Torino’s emblematic silhouette, the Mole Antonelliana tower. Started out as a synagogue in the 1800s, currently home of Italy’s Museum of Cinema.