While SemVer's binary compatibility guarantees restrict the types of changes that may be made within a library revision and make it difficult to remove an API, there are many other ways to influence how developers interact with your library.
@Deprecated
)Deprecation lets a developer know that they should stop using an API or class. All deprecations must be marked with a @Deprecated
code annotation as well as a @deprecated <explanation>
docs annotation (for Java) or @Deprecated(message = <explanation>)
(for Kotlin) explaining the rationale and how the developer should migrate away from the API.
Deprecations in Kotlin are encouraged to provide an automatic migration by specifying the replaceWith = ReplaceWith(<replacement>)
parameter to @Deprecated
in cases where the migration is a straightforward replacement and may specify level = DeprecationLevel.ERROR
(source-breaking) in cases where the API on track to be fully removed.
Deprecation is an non-breaking API change that must occur in a major or minor release.
APIs that are added during a pre-release cycle and marked as @Deprecated
within the same cycle, e.g. added in alpha01
and deprecated in alpha06
, must be removed before moving to beta01
.
NOTE While some APIs can safely be removed without a deprecation cycle, a full cycle of deprecate (with replacement) and release prior to removal is strongly recommended for APIs that are likely to have clients, including APIs referenced by the Android platform build and @RequiresOptIn
APIs that have shipped in a public beta.
@removed
or DeprecationLevel.HIDDEN
)Soft removal preserves binary compatibility while preventing source code from compiling against an API. It is a source-breaking change and not recommended.
Soft removals must do the following:
@RestrictTo(LIBRARY)
Java annotation as well as a @removed <reason>
docs annotation explaining why the API was removed.@Deprecated(message = <reason>, level = DeprecationLevel.HIDDEN)
explaining why the API was removed.This is a disruptive change and should be avoided when possible.
Soft removal is a source-breaking API change that must occur in a major or minor release.
Hard removal entails removing the entire implementation of an API that was exposed in a public release. Prior to removal, an API must be marked as @deprecated
for a full minor version (alpha
->beta
->rc
->stable), prior to being hard removed.
This is a disruptive change and should be avoided when possible.
Hard removal is a binary-breaking API change that must occur in a major release.
We do not typically deprecate or remove entire artifacts; however, it may be useful in cases where we want to halt development and focus elsewhere or strongly discourage developers from using a library.
Halting development, either because of staffing or prioritization issues, leaves the door open for future bug fixes or continued development. This quite simply means we stop releasing updates but retain the source in our tree.
Deprecating an artifact provides developers with a migration path and strongly encourages them -- through Lint warnings -- to migrate elsewhere. This is accomplished by adding a @Deprecated
and @deprecated
(with migration comment) annotation pair to every class and interface in the artifact.
To deprecate an entire artifact:
@Deprecated
and update the API files (example CL)The fully-deprecated artifact will be released as a deprecation release -- it will ship normally with accompanying release notes indicating the reason for deprecation and migration strategy, and it will be the last version of the artifact that ships. It will ship as a new minor stable release. For example, if 1.0.0
was the last stable release, then the deprecation release will be 1.1.0
. This is so Android Studio users will get a suggestion to update to a new stable version, which will contain the @deprecated
annotations.
After an artifact has been released as fully-deprecated, it can be removed from the source tree.