Random Musings on the N Developer Preview
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.
N is a bit of an “iceberg” release. What you see in the overviews is interesting, but there appears to be a lot more changing under the covers than may be obvious from those overviews. Partly, that is due to the switch to the OpenJDK, which I mused about previously.
Things To Start Thinking About Now
-
The multi-window support is going to get a lot of media attention, including in the short term. Moreover, multi-window support is opt-out, insofar as that your app will be resized by the user unless your
targetSdkVersion
is N (today, presumably 24 eventually) and you specifically declare that you do not want the activity to be resized. There are some exceptions, notably activities that fix their orientation viascreenOrientation
. But on the whole, your activity is getting resized, like it or not. Moreover, users are going to expect to be able to resize your activity. This is the sort of thing that you are going to want to test early and often, on various form factors. -
Compounding the above is that Android appears to be coming to the desktop. This has been rumored for a bit. Multi-window support clearly is designed for desktop-style usage. While the media today might focus on split-screen mode, my guess is that come late May, the media will focus on “freeform” mode (“Manufacturers of larger devices can choose to enable freeform mode, in which the user can freely resize each activity.”) What Google calls “freeform” mode sounds a whole lot like windowed desktop applications. But, beyond just the multi-window support, there are other changes that, to me, indicate that Android is coming to the desktop:
-
We now have dedicated keycodes for cut, copy, and paste, plus
onProvideKeyboardShortcuts()
inActivity
, suggesting greater emphasis on hardware keyboard input -
We now have
PointerIcon
and pointer-capture hooks inView
, suggesting greater emphasis on mouse/trackpad-style input -
There is now
FEATURE_ETHERNET
, and presumably a corresponding<uses-feature>
option, suggesting greater emphasis on hard-wired network connections
-
-
Doze mode was introduced in Android 6.0, to the consternation of some developers. At the time, it was limited to devices that were not moving (e.g., left on the nightstand overnight). As of Android N, Doze mode can kick in at any time if the device is not on a charger, even if it is moving. This will not change your app directly, but it will change how much your app is affected by Doze mode and the frequency of customer support issues that Doze mode may trigger.
-
One side-effect of the multi-locale support is that resource resolution gets a bit more complex. In particular, you need to put even more emphasis on having complete translations for language families, not partial ones. Right now, if you miss a string for some language family, the user will get whatever string you have in the default resource set (e.g.,
res/values/strings.xml
). With N, the user might get a string from a secondary locale. If you have enough holes in your translation set, the user might get a whole bunch of different languages appearing on the screen, assuming that the resource resolution is happening at the per-string level as it has been to date. Make sure that your translations are complete, both when you introduce the translation and when you add new user-facing strings over time. -
Also related to the multi-locale support, if you are one of those developers who has been overriding the user’s device locale within your app… test thoroughly on N, please.
-
The docs for the Data Saver feature state that your app needs to “gracefully handle restrictions to background data usage”. My interpretation is that Data Saver will behave a bit like app standby, insofar as you will have limited ability to access the Internet unless the user is actively using your app. This is another feature that you will want to test thoroughly.
-
To address Data Saver, you might be tempted to try using
ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS
to lead the user to add your app to the Data Saver whitelist, so you have normal background network access. However, bear in mind that Google has a similar feature for the battery saver whitelist… and trying to use that action got apps banned from the Play Store. At the moment, there is no similar language around the use of the Data Saver whitelist… but, then again, they didn’t tell you they were going to ban you for asking to be on the battery saver whitelist until after Android 6.0 shipped. -
Overall, the network security configuration is seriously cool for helping secure your app. One useful side-effect ties into all those emails people have been getting about broken
X509TrustManager
implementations. Some of those brokenTrustManager
implementations have been tied to trying to use self-signed certificates. Now, you can usedebug-overrides
to allow use of a self-signed certificate in your app, but only fordebug
builds. If I am understanding the usage correctly, this means that you can transparently use the self-signed certificate when needed (e.g., hitting your test server) without risking supporting that certificate in production releases. -
All the classic JUnit test case base classes, like
ActivityInstrumentationTestCase2
andActivityTestCase
, are officially deprecated. If you have not done so already, budget time in the next year or so to move over to the JUnit4 testing support. -
There is a new
FileUriExposedException
. It will be thrown if you use afile:
Uri
value. What is not completely clear is under what circumstances it will be thrown. (UPDATE 2016-03-14: It is thrown pretty much if you try using afile:
Uri
). There ispenaltyDeathOnFileUriExposure()
onStrictMode.VmPolicy.Builder
, which presumably triggers this exception. However, the vague wording suggests that perhaps N – or future versions of Android – might throw it by default, the way thatNetworkOnMainThreadException
gets thrown. To deal with this:-
If you receive
Uri
values from third-party apps, please do a decent job of supportingcontent:
Uri
values. This includes not being an idiot and thinking that these values all come fromMediaStore
or have file paths that you can derive. Please useopenInputStream()
,getType()
, and theOpenableColumns
with aContentResolver
to consume the content identified by theUri
. -
If you send
Uri
values to other apps (ACTION_VIEW
,ACTION_SEND
, etc.), continue moving over tocontent:
Uri
values. UseFileProvider
, perhaps supplemented by myLegacyCompatCursorWrapper
(to help deal with the aforementioned idiots). At minimum, isolate your methods that create theseUri
values into places that may make it easier for you to switch tocontent:
Uri
values in the future, in caseFileUriExposedException
starts getting thrown in production.
-
-
If you have been using
inPreferQualityOverSpeed
onBitmapFactory.Options
, that is now deprecated. The docs state that on N the flag is ignored because “the output will always be high quality”. In related news, all the children in Lake Wobegon are above-average, and Bruce Banner is always angry. -
If you look at the N API differences report, you might have a slight panic attack and think that Google removed
fromHtml()
andtoHtml()
on theHtml
class. That appears to be a bug in how the API differences report got generated. The methods you are using are still there. However, they have been supplemented by additional methods that take flags as a parameter, offering greater control over how the HTML is interpreted or generated. This, in turn, suggests that this code is getting overhauled, which would be wonderful. -
According to the API differences report,
StringBuilder
(and the legacyStringBuffer
) no longer implementAppendable
. This appears to be a bug in the report, as the JavaDocs shows they both still implementAppendable
. Since they implementAppendable
in Java 8, one presumes that Android’s edition of these classes will continue to implementAppendable
as well.
Other Bits of Goodness (For Some Definition of “Goodness”)
- Google continues to pile on more storage options, this time in the
form of
ACTION_OPEN_EXTERNAL_DIRECTORY
andandroid.os.storage.StorageVolume
. Near as I can tell, the idea is to avoidREAD_EXTERNAL_STORAGE
andWRITE_EXTERNAL_STORAGE
, and possibly grant direct access to more of removable storage, by means of asking users for long-term fine-grained permission grants. This sounds reasonable. However, far too many developers are still coming up to speed on things like the Storage Access Framework, introduced back in Android 4.4, and the simultaneous restrictions on removable storage. All this will do is add to the confusion. Having the “For more information” link in the preview documentation lead nowhere is not a good start.
2016-03-10 UPDATE: Ian Lake pointed out that the “scoped directory access” documentation is now live.
-
android.auditing.SecurityLog
seems interesting (logs adb shell commands, etc.). -
AlarmManager
now has in-process alarms.set()
,setExact()
, andsetWindow()
have versions that take anOnAlarmListener
and call a callback method on it when the time arrives. -
We now have
commitNow()
as an option, for executing a synchronousFragmentTransaction
.commit()
, by contrast, is asynchronous. -
The
android.webkit
package now hasServiceWorker
-related classes. -
WebSettings
has asetDisabledActionModeMenuItems()
, suggesting that you can block some of the standard cut/copy/paste operations, which is particularly useful if they interfere with the Web content that you are rendering. -
shouldOverrideUrlLoading(WebView, String)
onWebViewClient
is deprecated, replaced withshouldOverrideUrlLoading(WebView, WebResourceRequest)
. -
AbsSeekBar
supports tick marks, mostly for the benefit ofSeekBar
, presumably. -
Chronometer
supports a countdown mode, including in app widgets viaRemoteViews
.
Unsolved Mysteries
-
There are
ACTION_PACKAGES_SUSPENDED
andACTION_PACKAGES_UNSUSPENDED
actions onIntent
. It is unclear what “suspended” means in this context. UPDATE 2016-03-14: Andriy Petruk pointed out that this probably ties into Android for Work. -
There is an
ACTION_QUICK_VIEW
defined onIntent
for a “quick viewer for a URI or list of URIs”. It is unclear what such a viewer is, whether we can supply a viewer, and so on. But I’m sure that it’s quick. -
It is unclear what
AutomaticZenRule
is, but I imagine that Phil Jackson approves. -
We have had
isolatedProcess
services for a bit, where they run in a separate permission-less process. N gives usexternalService
, which works in conjunction withisolatedProcess
and allows the service to “run in the calling application’s package”. It is unclear whether “run in the calling application’s package” refers to storage, permissions, or something else.
One Scary Thought
Future releases of Android may deprecate additional implicit broadcasts, as well as unbound background services. For this reason, you should avoid or remove dependencies on manifest-declared receivers for implicit broadcasts, as well as on background services.
This comes from the discussion over the changes to CONNECTIVITY_ACTION
,
where you can no longer register for it in the manifest.
The fact that Google might move more implicit broadcasts into the
registerReceiver()
-only bucket does not surprise me. To some extent,
I am surprised that they haven’t done more of this to date.
What scares me is the suggestion that unbound services might no longer be supported.
If they had said that FLAG_START_STICKY
was deprecated, I could understand.
Or, if they had said that processes with services might be terminated
more quickly, I could understand.
Wiping out IntentService
and other uses of the command pattern with
services seems a bit over the top. Apparently, they are going to try
to have developers shoehorn all background work into discrete supported
categories, with specialized service subclasses (e.g., JobScheduler
),
as a way of reining in power and memory consumption.
I have some difficulty believing that this will turn out well.
What Now?
My guess for a release timeframe on N is August 2016, plus or minus a month. The developer preview came out a couple of months earlier than before; August would be a couple of months earlier than when the new major Android releases have shipped.
I’ll be starting to cover the N Developer Preview in the next book update, due out later this month.