In this document
- Apps targeting all API levels
- Background execution limits
- Android background location limits
- App shortcuts
- Locales and internationalization
- Alert windows
- Input and navigation
- Web form autofill
- Accessibility
- Networking and HTTP(S) connectivity
- Bluetooth
- Seamless Connectivity
- Security
- Privacy
- Logging of uncaught exceptions
- Contacts provider usage stats change
- Collection handling
- Android enterprise
- Apps targeting Android O
API Differences
See Also
Along with new features and capabilities, Android O includes a variety of system and API behavior changes. This document highlights some of the key changes that you should understand and account for in your apps.
Most of these changes affect all apps, regardless of what version of Android they target. However, several changes only affect apps targeting Android O. To maximize clarity, this page is divided into two sections: Apps targeting all API levels and Apps targeting Android O.
Apps targeting all API levels
These behavior changes apply to
Background execution limits
As one of the changes that Android O introduces to improve battery life, when your app enters the cached state, with no active components, the system releases any wakelocks that the app holds.
In addition, to improve device performance, the system limits certain behaviors by apps that are not running in the foreground. Specifically:
- Apps that are running in the background now have limits on how freely they can access background services.
- Apps cannot use their manifests to register for most implicit broadcasts (that is, broadcasts that are not targeted specifically at the app).
By default, these restrictions only apply to apps that target O. However, users can enable these restrictions for any app from the Settings screen, even if the app has not targetted O.
Android O also includes the following changes to specific methods:
- The
startService()method now throws anIllegalStateExceptionif an app targeting Android O tries to use that method in a situation when it isn't permitted to create background services. - The new
Context.startForegroundService()method starts a foreground service. The system allows apps to callContext.startForegroundService()even while the app is in the background. However, the app must call that service'sstartForeground()method within five seconds after the service is created.
For more information, see Background Execution Limits.
Android background location limits
In order to preserve battery, user experience, and system health, background apps receive location updates less frequently when used on a device running Android O. This behavior change affects all apps that receive location updates, including Google Play services.
These changes affect the following APIs:
- Fused Location Provider (FLP)
- Geofencing
- GNSS Measurements
- Location Manager
- Wi-Fi Manager
To ensure that your app runs as expected, complete the following steps:
- Review your app's logic and ensure that you're using the latest location APIs.
- Test that your app exhibits the behavior that you expect for each use case.
- Consider using the Fused Location Provider (FLP) or geofencing to handle the use cases that depend on the user's current location.
For more information about these changes, see Background Location Limits.
App shortcuts
Android O includes the following changes to app shortcuts:
- The
com.android.launcher.action.INSTALL_SHORTCUTbroadcast no longer has any effect on your app, because it is now a private, implicit broadcast. Instead, you should create an app shortcut by using therequestPinShortcut()method from theShortcutManagerclass. - The
ACTION_CREATE_SHORTCUTintent can now create app shortcuts that you manage using theShortcutManagerclass. This intent can also create legacy launcher shortcuts that don't interact withShortcutManager. Previously, this intent could create only legacy launcher shortcuts. - Shortcuts created using
requestPinShortcut()and shortcuts created in an activity that handles theACTION_CREATE_SHORTCUTintent are now fully-fledged app shortcuts. As a result, apps can now update them using the methods inShortcutManager. - Legacy shortcuts retain their functionality from previous versions of Android, but you must convert them to app shortcuts manually in your app.
To learn more about changes to app shortcuts, see the Pinning Shortcuts and Widgets preview feature guide.
Locales and internationalization
Android 7.0 (API level 24) introduced the concept of being able to
specify a default Category Locale, but some APIs continued to use the
generic Locale.getDefault()
method, without arguments, when they should have instead used default DISPLAY category Locale. In Android O, the
following methods now use Locale.getDefault(Category.DISPLAY)
instead of Locale.getDefault():
Locale.getDisplayScript(Locale) also
falls back to Locale.getDefault() when the
displayScript value specified for the Locale
argument is not available.
Additional locale and internationalization-related changes are as follows:
- Calling
Currency.getDisplayName(null)throws aNullPointerException, matching the documented behavior. - Time zone name parsing has changed. Previously,
Android devices used the system clock value sampled at boot
time to cache the time zone names used for parsing date
times. As a result, parsing could be negatively affected if the system
clock was wrong at boot time or in other, rarer cases.
Now, in common cases the parsing logic uses ICU and the current system clock value when parsing time zone names. This change provides more correct results, which may differ from earlier Android versions when your app uses classes like
SimpleDateFormat. - Android O updates the version of ICU to version 58.
Alert windows
If an app uses the SYSTEM_ALERT_WINDOW
permission and uses one of the following window types to attempt to display
alert windows above other apps and system windows:
...then these windows always appear beneath the windows that use the
TYPE_APPLICATION_OVERLAY window
type. If an app targets Android O, the app uses the
TYPE_APPLICATION_OVERLAY
window type to display alert windows.
For more information, see the Common window types for alert windows section within the behavior changes for Apps targeting Android O.
Input and navigation
With the advent of Android apps on Chrome OS and other large form factors, such as tablets, we're seeing a resurgence of keyboard navigation use within Android apps. Within Android O, we've re-addressed using the keyboard as a navigation input device, resulting in a more reliable, predictable model for arrow- and tab-based navigation.
In particular, we've made the following changes to element focus behavior:
-
If you haven't defined any focus state colors for a
Viewobject (either its foreground or background drawable), the framework now sets a default focus highlight color for theView. This focus highlight is a ripple drawable that's based on the activity's theme.If you don't want a
Viewobject to use this default highlight when it receives focus, set theandroid:defaultFocusHighlightEnabledattribute tofalsein the layout XML file containing theView, or pass infalsetosetDefaultFocusHighlightEnabled()in your app's UI logic. - To test how keyboard input affects UI element focus, you can enable the Drawing > Show layout bounds developer option. In Android O, this option displays an "X" icon over the element that currently has focus.
Also, all toolbar elements in Android O are automatically keyboard navigation clusters, making it easier for users to navigate into and out of each toolbar as a whole.
To learn more about how to improve support for keyboard navigation within your app, read the Supporting Keyboard Navigation guide.
Web form autofill
Now that the Android Autofill
Framework provides built-in support for autofill functionality, the
following methods related to WebView objects have changed
for apps installed on devices running Android O:
WebSettings-
- The
getSaveFormData()method now returnsfalse. Previously, this method returnedtrueinstead. - Calling
setSaveFormData()no longer has any effect.
- The
WebViewDatabase-
- Calling
clearFormData()no longer has any effect. - The
hasFormData()method now returnsfalse. Previously, this method returnedtruewhen the form contained data.
- Calling
Accessibility
Accessibility services are now aware of all
ClickableSpan instances within your app's
TextView objects.
To learn more about how to make your app more accessible, see Accessibility.
Networking and HTTP(S) connectivity
Android O includes the following behavior changes to networking and HTTP(S) connectivity:
- OPTIONS requests with no body have a
Content-Length: 0header. Previously they had noContent-Lengthheader. - HttpURLConnection normalizes URLs containing empty paths by appending
a slash after the host or authority name with a slash. For example, it
converts
http://example.comtohttp://example.com/. - A custom proxy selector set via ProxySelector.setDefault() only targets the address (scheme, host and port) of a requested URL. As a result, proxy selection may only be based on those values. A URL passed to a custom proxy selector does not include the requested URL’s path, query parameters, or fragments.
- URIs cannot contain empty labels.
Previously, the platform supported a workaround to accept empty labels in host names, which is an illegal use of URIs. This workaround was for compatibility with older libcore releases. Developers using the API incorrectly would see an ADB message: "URI example..com has empty labels in the hostname. This is malformed and will not be accepted in future Android releases." Android O removes this workaround; the system returns null for malformed URIs.
- Android O’s implementation of HttpsURLConnection does not perform insecure TLS/SSL protocol version fallback.
- Handling of tunneling HTTP(S) connections has changed as follows:
- When tunneling HTTPS connection over connection, the system correctly places the port number (:443) in the Host line when sending this information to an intermediate server. Previously, the port number only occurred in the CONNECT line.
- The system no longer sends user-agent and proxy-authorization
headers from a tunneled request to the proxy server.
The system no longer sends a proxy-authorization header on a tunneled Http(s)URLConnection to the proxy when setting up the tunnel. Instead, the system generates a proxy-authorization header, and sends it to the proxy when that proxy sends HTTP 407 in response to the initial request.
Similarly, the system no longer copies the user-agent header from the tunneled request to the proxy request that sets up the tunnel. Instead, the library generates a user-agent header for that request.
- The
send(java.net.DatagramPacket)method throws a SocketException if the previously executed connect() method failed.- DatagramSocket.connect() sets a pendingSocketException if there is an internal error. Prior to Android O, a subsequent recv() call threw a SocketException even though a send() call would have succeeded. For consistency, both calls now throw a SocketException.
- InetAddress.isReachable() attempts ICMP before falling back to TCP Echo
protocol.
- Some hosts that block port 7 (TCP Echo), such as google.com, may now become reachable if they accept ICMP Echo protocol.
- For truly unreachable hosts, this change means that twice the amount of time is spent before the call returns.
Bluetooth
Android O makes the following changes to the length of
the data that the ScanRecord.getBytes()
method retrieves:
- The
getBytes()method makes no assumptions as to the number of bytes received. Therefore, apps should not rely on any minimum or maximum number of bytes returned. Instead, they should evaluate the length of the resulting array. - Bluetooth 5-compatible devices may return data length exceeding the previous maximum of ~60 bytes.
- If a remote device does not provide a scan response, fewer than 60 bytes may be returned as well.
Seamless Connectivity
Android O makes a number of improvements to Wi-Fi Settings to make it easier to choose the Wi-Fi network that offers the best user experience. Specific changes include:
- Stability and reliability improvements.
- A more intuitively readable UI.
- A single, consolidated Wi-Fi Preferences menu.
- On compatible devices, automatic activation of Wi-Fi when a high quality saved network is nearby.
Security
Android O includes the following security-related changes:
- The platform no longer supports SSLv3.
- When establishing an HTTPS connection to a server that incorrectly
implements TLS protocol-version negotiation,
HttpsURLConnectionno longer attempts the workaround of falling back to earlier TLS protocol versions and retrying. - Android O applies a Secure Computing (SECCOMP) filter to all apps. The list of allowed syscalls is restricted to those exposed through bionic. Although there are several other syscalls provided for backwards compatibility, we recommend against their use.
- Your app's
WebViewobjects now run in multiprocess mode. Web content is handled in a separate, isolated process from the containing app's process for enhanced security. -
You can no longer assume that APKs reside in directories whose names end
in -1 or -2. Apps should use
sourceDirto get the directory, and not rely on the directory format directly. - For information about security enhancements related to use of native libraries, see Native Libraries.
For additional guidelines on making your app more secure, see Security for Android Developers.
Privacy
Android O makes the following privacy-related changes to the platform.
- The platform now handles identifiers differently.
-
For apps that were installed prior to an OTA to a version of Android O
(API level 26), the value of
ANDROID_IDremains the same unless uninstalled and then reinstalled after the OTA. To preserve values across uninstalls after OTA, developers can associate the old and new values by using Key/Value Backup. - For apps installed on a device running Android O, the value of
ANDROID_IDis now scoped per app signing key, as well as per user. The value ofANDROID_IDis unique for each combination of app-signing key, user, and device. As a result, apps with different signing keys running on the same device no longer see the same Android ID (even for the same user). - The value of
ANDROID_IDdoes not change on package uninstall or reinstall, as long as the signing key is the same (and the app was not installed prior to an OTA to a version of O). - The value of
ANDROID_IDdoes not change even if a system update causes the package signing key to change.
For a simple, standard system to monetize apps, use Advertising ID. Advertising ID is a unique, user-resettable ID for advertising, provided by Google Play services.
-
For apps that were installed prior to an OTA to a version of Android O
(API level 26), the value of
net.hostname system property produces a null
result.Logging of uncaught exceptions
If an app installs a Thread.UncaughtExceptionHandler that does
not call through to the default Thread.UncaughtExceptionHandler,
the system does
not kill the app when an uncaught exception occurs. Starting from
Android O, the system logs the exception stacktrace in this
situation; in earlier versions of the platform, the system would not have
logged the exception stacktrace.
We recommend that custom Thread.UncaughtExceptionHandler
implementations always call through to
the default handler; apps that follow this recommendation are unaffected by
the change in Android O.
Contacts provider usage stats change
In previous versions of Android, the Contacts Provider component
allows developers to get usage data for each contact. This usage data
exposes information for each email address and each phone number associated
with a contact, including the number of times the contact has been contacted
and the last time the contact was contacted. Apps that request the
READ_CONTACTS
permission can read this data.
Apps can still read this data if they request
READ_CONTACTS
permission. Starting in Android O, queries for usage data return
approximations rather than exact values. The Android system maintains the
exact values internally, so this change does not affect the
auto-complete API.
This behavior change affects the following query parameters:
Collection handling
AbstractCollection.removeAll()
and AbstractCollection.retainAll()
now always throw a NullPointerException; previously, the
NullPointerException was not thrown when the collection was
empty. This change makes the behavior consistent with the documentation.
Android enterprise
Android O changes the behavior of some APIs and features for enterprise apps, including device policy controllers (DPCs). The changes include:
- New behaviors to help apps support work profiles on fully managed devices.
- Changes to system update handling, app verification, and authentication to increase device and system integrity.
- Improvements to the user experience for provisioning, notifications, the Recents screen, and always-on VPN.
To see the all the enterprise changes in Android O and learn how they might affect your app, read Android in the Enterprise.
Apps targeting Android O
These behavior changes apply exclusively to apps that are targeting
the O platform or higher. Apps that compile against Android O or higher
or set targetSdkVersion to Android O or higher must modify
their apps to support these behaviors properly, where applicable to the app.
Alert windows
Apps that use the SYSTEM_ALERT_WINDOW
permission can no longer use the following window types to display alert windows
above other apps and system windows:
Instead, apps must use a new window type called
TYPE_APPLICATION_OVERLAY.
When using the
TYPE_APPLICATION_OVERLAY window
type to display alert windows for your app, keep the following characteristics
of the new window type in mind:
- An app's alert windows always appear under critical system windows, such as the status bar and IMEs.
- The system can move or resize windows that use the
TYPE_APPLICATION_OVERLAYwindow type to improve screen presentation. - By opening the notification shade, users can access settings to block an
app from displaying alert windows shown using the
TYPE_APPLICATION_OVERLAYwindow type.
Content change notifications
Android O changes how
ContentResolver.notifyChange()
and registerContentObserver(Uri, boolean, ContentObserver)
behave for apps targeting Android O.
These APIs now require that a valid ContentProvider
is defined for the authority in all Uris. Defining a valid ContentProvider with relevant permissions will
help defend your app against content changes from malicious apps, and prevent you
from leaking potentially private data to malicious apps.
View focus
Clickable View objects are now also focusable by
default. If you want a View object to be clickable but not
focusable, set the
android:focusable attribute to false in the layout
XML file containing the View, or pass in false
to setFocusable() in your app's UI
logic.
Security
If your app's network security configuration
opts
out of supporting cleartext traffic, your app's
WebView objects cannot access websites over HTTP. Each
WebView object must use HTTPS instead.
For additional guidelines on making your app more secure, see Security for Android Developers.
Account access and discoverability
Apps can no longer get access
to user accounts unless the authenticator owns the accounts or the
user grants that access. The
GET_ACCOUNTS permission
is no longer sufficient. To be granted access to an account, apps should
either use AccountManager.newChooseAccountIntent()
or an authenticator-specific
method. After getting access to accounts, an app can can call
AccountManager.getAccounts()
to access them.
Android O deprecates
LOGIN_ACCOUNTS_CHANGED_ACTION. Apps
should instead use
addOnAccountsUpdatedListener()
to get updates about accounts during runtime.
For information about new APIs and methods added for account access and discoverability, see Account Access and Discoverability in the New APIs section of this document.
Privacy
The following changes affect privacy in Android O.
-
The system properties
net.dns1,net.dns2,net.dns3, andnet.dns4are no longer available, a change that improves privacy on the platform. -
To obtain networking information such as DNS servers, apps with
the
ACCESS_NETWORK_STATEpermission can register aNetworkRequestorNetworkCallbackobject. These classes are available in Android 5.0 (API level 21) and higher. -
Build.SERIAL is deprecated.
Apps needing to know the hardware serial number should instead
use the new
Build.getSerial()method, which requires theREAD_PHONE_STATEpermission. -
The
LauncherAppsAPI no longer allows work profile apps to get information about the primary profile. When a user is in a work profile, theLauncherAppsAPI behaves as if no apps are installed in other profiles within the same profile group. As before, attempts to access unrelated profiles causes SecurityExceptions.
Permissions
Prior to Android O, if an app requested a permission at runtime and the permission was granted, the system also incorrectly granted the app the rest of the permissions that belonged to the same permission group, and that were registered in the manifest.
For apps targeting Android O, this behavior has been corrected. The app is granted only the permissions it has explicitly requested. However, once the user grants a permission to the app, all subsequent requests for permissions in that permission group are automatically granted.
For example, suppose an app lists both READ_EXTERNAL_STORAGE and
WRITE_EXTERNAL_STORAGE in its manifest.
The app requests READ_EXTERNAL_STORAGE and
the user grants it. If the app targets API level 24 or lower, the system also
grants WRITE_EXTERNAL_STORAGE at the same
time, because it belongs to the same STORAGE permission group and is also
registered in the manifest. If the app targets Android O, the system grants
only READ_EXTERNAL_STORAGE at that time;
however, if the app later requests WRITE_EXTERNAL_STORAGE, the system immediately
grants that privilege without prompting the user.
Media
- The framework performs audio ducking. Applications do not lose focus
in the case of
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK. New APIs are available for applications that need to pause instead of ducking. Note that this behavior is not implemented in the Android O Developer Preview 1 release. - When the user takes a phone call, active media streams mute for the duration of the call.
- All audio-related APIs should use
AudioAttributesrather than audio stream types to describe the audio playback use case. Continue to use audio stream types for volume controls only. Other uses of stream types (for example, the deprecatedAudioTrack constructor) still work, but the system logs this as an error. - When using an
AudioTrack, if the application requests a large enough audio buffer, the framework will try to use the deep buffer output if it is available. - In Android O the handling of media button events is different:
- Handling media buttons in a UI activity has not changed: foreground activities still get priority in handling media buttons.
- If the foreground activity does not handle the media button, the system routes media buttons to the app that most recently played audio locally. The active status, flags, and playback state of a media session are no longer considered when determining which app receives media button events. Media sessions can receive media button events even after the app calls setActive(false).
- If the app's media session has been released, the system sends the media button event to the app's MediaButtonReceiver, if it has one.
- For every other case, the system discards the media button event. Better to not play anything at all than start playing the wrong app.
The new media button routing logic is summarized in the following diagram:
Native libraries
In apps targeting Android O, native libraries no longer load if they contain any load segment that is both writable and executable. Some apps might stop working because of this change if they have native libraries with incorrect load segments. This is a security-hardening measure.
For more information, see Writable and Executable Segments.
As with earlier developer-preview releases, Android O also makes all linker-related problems more visible. Linker changes are tied to the API level that an app targets. If there is a linker change at the targeted API level, the app cannot load the library. If you are targeting an API level lower than the API level where the linker change occurs, logcat shows a warning. During a preview release, linker-related problems not only appear in logcat, but also show up as toasts. This change improves visibility of issues before the API level at which a warning becomes an error.
Collection handling
In Android O,
Collections.sort() is implemented on
top of List.sort(). The reverse
was true in Android 7.x (API levels 24 and 25):
The default implementation of List.sort()
called Collections.sort().
This change allows Collections.sort()
to take advantage of optimized List.sort()
implementations, but has the following constraints:
Implementations of
List.sort()must not callCollections.sort(), because doing so would result in stack overflow due to infinite recursion. Instead, if you want the default behavior in yourListimplementation, you should avoid overridingsort().If a parent class implements
sort()inappropriately, it’s usually fine to overrideList.sort()with an implementation built on top ofList.toArray(),Arrays.sort(), andListIterator.set(). For example:@Override public void sort(Comparator<? super E> c) { Object[] elements = toArray(); Arrays.sort(elements, c); ListIterator<E> iterator = (ListIterator<Object>) listIterator(); for (Object element : elements) { iterator.next(); iterator.set((E) element); } }In most cases, you can also override
List.sort()with an implementation that delegates to different default implementations depending on API level. For example:@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }If you’re doing the latter only because you want to have a
sort()method available on all API levels, consider giving it a unique name, such assortCompat(), instead of overridingsort().-
Collections.sort()now counts as a structural modification in List implementations that callsort(). For example, in versions of the platform prior to Android O, iterating over anArrayListand callingsort()on it partway through the iteration would have thrown aConcurrentModificationExceptionif the sorting was done by callingList.sort().Collections.sort()did not throw an exception.This change makes the platform behavior more consistent: Either approach now results in a
ConcurrentModificationException.
Class-loading behavior
Android O checks to make sure that class loaders do not
break the assumptions of the runtime when loading new classes. These checks are
performed whether the class is referenced from Java (from
forName()),
Dalvik bytecode, or JNI. The platform does not intercept direct calls from Java to the
loadClass() method, nor does it check
the results of such calls. This behavior should not affect the functioning of well-behaved
class loaders.
The platform checks that the descriptor of the class that the class loader returns
matches the expected descriptor. If the returned descriptor does not match,
the platform throws a NoClassDefFoundError error, and stores in
the exception a detailed message noting the discrepancy.
The platform also checks that the descriptors of the requested classes are valid. This
check catches JNI calls that indirectly load classes such as GetFieldID(),
passing invalid descriptors to those classes. For example, a field with signature
java/lang/String is not found because that signature is invalid;
it should be Ljava/lang/String;.
This is different from a JNI call to FindClass()
where java/lang/String is a valid fully-qualified name.
Android O does not support having multiple class loaders try to define classes
using the same DexFile object. An attempt to do so causes the Android runtime to throw an
InternalError
error with the message "Attempt to register dex file <filename>
with multiple class loaders".
DexFile API is now deprecated, and you are strongly encouraged to use
one of the platform classloaders, including PathClassLoader or
BaseDexClassLoader, instead.
Note: You can create multiple class loaders that reference the
same APK or JAR file container from the file system. Doing so normally does not
result in much memory overhead: If DEX files in the container are stored instead of
compressed, the platform can perform an mmap operation on them rather than
directly extracting them. However, if the platform must extract the DEX file from the container,
referencing a DEX file in this fashion may consume a lot of memory.
In Android, all class loaders are considered parallel-capable. When multiple threads race to load the same class with the same class loader, the first thread to complete the operation wins, and the result is used for the other threads. This behavior occurs regardless of whether the class loader has returned the same class, returned a different class, or thrown an exception. The platform silently ignores such exceptions.
Caution: In versions of the platform lower than Android O, breaking these assumptions can lead to defining the same class multiple times, heap corruption due to class confusion, and other undesirable effects.