Random Musings on the O Developer Preview 2

Each time Google releases a new developer preview, I rummage through the API differences report and the high-level overviews, to see if there are things that warrant more attention from developers, with an emphasis on mainstream features that any developer might reasonably use. I also tend to emphasize things that may not get quite as much attention, because they are buried in the JavaDocs.

So, here are my notes on O Developer Preview 2 (ODP2).

What Did I Say Last Time That Is No Longer a Concern?

Two months ago, I published my random musings on ODP1.

Of note, my concerns about multi-display testing were somewhat abated by realizing that the simulated secondary displays handled it well.

Otherwise, what I had in that original post is mostly still relevant.

What’s Interesting in the Release Notes

Each developer preview has its section of the release notes. In the case of ODP2:

  • The biggest concern is “Even for apps not targeting O, users can use the Settings screen to enable background execution limits.” This implies that all developers need to concern themselves with the changes in Service behavior, the semi-ban on implicit broadcasts, and the changes in background location behavior. Previously, this was limited to developers who jumped to targetSdkVersion of O or higher. However, I cannot find where in Settings that the user can make this change. I cannot even find it in Developer Options. So, it is unclear how much of an issue this is.

  • The release notes state that “Developers using FCM/GCM with Android O should update their Google Play services SDK to version ≥ 10.2.1, which is available from the SDK manager in Android Studio.” That is curious, as IIRC, this raises the minSdkVersion to 14, meaning that it is even firmer official Google policy to leave Android 2.x devices in the dust. This is in the “Known Issues” portion of the release notes, so it may be that this is a temporary requirement.

  • The remaining findViewById() implementations (Activity, Dialog, etc.) have now been updated to return T rather than View, for consistency.

  • ODP1’s startServiceInForeground() on NotificationManager has been moved to startForegroundService() on Context, which is a nice simplification.

  • As was discussed at Google I|O, there are new APIs for downloading fonts on the fly from a font provider.

What’s Interesting in the “Features and APIs” Page?

For some reason, there are changes to Android that show up on the “Android O Features and APIs” page but are not mentioned in the release notes.

Of note:

  • JobScheduler has a new set of behaviors. A JobService can now have a work queue, with an eye towards replacing IntentService. And you can attach a ClipData object to a JobInfo, to be able to not only pass a Uri with the job, but to pass along any permissions you have for the content identified by the Uri (e.g., a Uri that you received from ACTION_GET_CONTENT or ACTION_OPEN_DOCUMENT). Also, you have new limits that you can place on jobs via JobInfo.Builder, including setRequiresBatteryNotLow() and setRequiresStorageNotLow().

  • VolumeShaper, rather than being a tool for managing 1980’s “big hair”, is an option for performing fade-in/fade-out/cross-fade sorts of audio transitions.

What’s Interesting in the API Diffs Report?

Where most of the “under the covers” stuff shows up is in seeing the diffs between the ODP1 and ODP2 APIs. There are more changes here than I would have expected.

Of note:

  • ActivityManager getRunningServices() is deprecated, and it will return only an app’s own services. This is part of the continued crackdown on apps knowing what other apps are doing.

  • Your ServiceConnection implementations will now need to add an onBindingDied() method. This will be called if the binding is permanently dead, requiring a fresh bindService() call. Now, onServiceDisconnected() represents a temporary suspension of the connection, but you may get called with onServiceConnected() again later on, when the service starts back up. AFAIK, this represents a change in onServiceDisconnected() behavior.

  • PendingIntent now has a getForegroundService() method. This works like getService(), but apparently it will use startForegroundService() instead of startService().

  • The Activity and Fragment onMultiWindowModeChanged() and onPictureInPictureModeChanged() methods now take a Configuration object as a parameter.

  • The multi-display APIs now offer an onMovedToDisplay() method on Activity, to find out when it is moved to some other display.

  • Fragment now has getLayoutInflater(), saving you from having to get one from the hosting Activity.

  • The autofill classes and methods switched from a capital F (AutoFill...) to a lowercase f (Autofill...). I eagerly await ODP3, where the lowercase f will be replaced by some other Unicode glyph that happens to resemble an f.

  • Beyond the “f”-ing changes, autofill has had other overhauls in its API. Apps can now provide hints as to the roles of views, and there are a bunch of new classes (FilLContext, FillEventHistory, SaveInfo, etc.). I suspect that my sample apps will need a significant overhaul.

  • `Bundle` now offers to store `UUID` values, though I argue that this should be in `BaseBundle`

    (UPDATE 2017-05-23: never mind, it’s being pulled from the API, apparently)

  • There is a new suite of classes for IPsec, starting with IpSecManager.

  • Chronometer now offers isTheFinalCountDown(), possibly in homage to a GEICO commercial.

What’s Interesting When You Try to Use ODP2?

The current release build of Android Studio (2.3.2) does not support ODP2, despite the fact that it had supported ODP1, and despite the fact that the current release build of Android Studio has supported then-current developer previews in the past. I find it curious that Google thinks so little about release builds of their IDE. Your code will still build and run just fine with Android Studio 2.3.2, but you will get lots of unrecognized symbol errors in the Java editor, along with related limitations (e.g., code completion).