Random Musings on the N Developer Preview 3

Each time Google releases a new developer preview, I try to talk about the changes that Google isn’t talking about.

N Developer Preview 3 (NDP3) represents another incremental change over N Developer Previews 1 and 2. Google did not bother with an announcement blog post, AFAICT, though there are some release notes.

This post outlines some things that have caught my eye in NDP3.

Regressions and Changes… Compared to Production Android

View offers post() and postDelayed() methods, as does Handler. On the whole, I have been steering developers to use the ones on View, as you pretty much always have a widget available, so there is little sense in creating a Handler instance just for post() and postDelayed(). However, NDP3 makes a slight change here:

If an app posts Runnable tasks to a View, and the View is not attached to a window, the system queues the Runnable task with the View; the Runnable task does not execute until the View is attached to a window.

For a lot of uses of post(), this will not be a problem. postDelayed() might get more interesting, particularly if you are using a “postDelayed() loop” (postDelayed() invoking a Runnable that calls postDelayed() to schedule itself again). That loop will only work so long as the View you are using is attached to a Window. If you are concerned about this, beyond testing your existing implementation, you might consider switching to a Handler instance for postDelayed().


  • The week number feature on CalendarView is now deprecated
  • The embedded CalendarView in DatePicker is now deprecated and is “not supported by Material-style calendar mode”.

Regresssions and Changes… Compared to NDP2

The ShortcutsManager added in NDP2 still exists in NDP3, but the release notes indicate that it will be retired in a future developer preview. I would not recommend investing further time in it.

Other Stuff in NDP3

There are other curiosities tucked into the API differences report, above and beyond the items called out in the release notes:

  • There is now an ACTION_SHOW_APP_INFO Intent action, to “launch an activity showing the app information”. This appears to be tied to the Play Store and other app installation channels, suggesting that you can use this to display information about apps that are not yet installed.

  • If you create an ACTION_CHOOSER Intent directly (rather than via the createChooser() helper method), you can add EXTRA_EXCLUDE_COMPONENTS to list particular components that should be excluded from the list of choices. This is very handy for cases where you have your own activity that handles some implicit Intent, but you specifically want to open some Uri in any other activity handling that type of content. For example, perhaps you are having difficulty rendering the content, and you want to allow the user to try viewing that content in a third-party app.

  • There is a new MessagingStyle for Notification, which is a “helper class for generating large-format notifications that include multiple back-and-forth messages of varying types between any number of people”. I have not tried this yet to determine whether it is something that might be specific to certain form factors (e.g., Wear) or whether it is available across the board.

  • Some options that we have on JobScheduler, such as “only while charging”, and “only while idle”, are now available on DownloadManager via methods on DownloadManager.Request.

  • stopForeground() is being migrated from taking a boolean (whether or not to remove the Notification) to an int, with STOP_FOREGROUND_REMOVE and STOP_FOREGROUND_DETACH options.

  • NDP1 added addTriggerContentUri() to JobScheduler, to allow us to monitor a ContentProvider for changes without having an always-running service. NDP3 adds setTriggerContentUpdateDelay(), to postpone running the job until the content has stabilized, so jobs do not run multiple times for a series of minor changes to the content. setTriggerContextMaxDelay() sets a cap on that delay. Between those two, you can have a modicum of control over how frequently your content-related jobs are invoked.

  • A new android.view.PixelCopy method allows you to asynchronously(?) copy the contents of a Surface to a Bitmap, with a callback when that work is completed.

Bugs in NDP3

Some of the bugs that I filed against NDP1 and NDP2 were fixed, particularly ones related to quick-settings tiles.

However, some bugs that I filed are still outstanding, such as:

I also have not yet confirmed whether the FLAG_LAUNCH_ADJACENT bug that I filed has been fixed… as I cannot get FLAG_LAUNCH_ADJACENT to work at all anymore. I am still investigating this.

I am sure that many more things changed in NDP3 than I caught in the past couple of hours. And most of what I pointed out in NDP1 and NDP2 still hold true.

Learn second-generation Android app development — with Kotlin and the Android Jetpack — through CommonsWare’s Android app development training!