@Nullable, @NonNull
用于修饰变量/参数/返回值. @Nullbale表示可空, @NonNull表示非空.
以下行为会生成警告:
-
将null/可空值赋值给非空变量/参数/字段
-
未进行null检查而直接调用可空值的方法/字段
此外, null注解也作用于Kotlin于Java交互:
@NonNull
String foo(@Nullable String a, @NonNull String b) {}
对应Kotlin函数签名:
fun foo(a: String?, b: String): String
Resource ID
表示目标资源ID的类型.
任意类型资源ID: @AnyRes
示例:
fun @receiver:AnyRes Int.uri() = "${SCHEME_ANDROID_RESOURCE}://${BuildConfig.APPLICATION_ID}/$this"
指定类型资源ID:
@StringRes
, @LayoutRes
, @DrawableRes
, @DimenRes
, @ColorRes
, @InterpolatorRes
, @IntegerRes
,
@IdRes
, @StyleRes
, @StyleableRes
, @TransitionRes
, @XmlRes
, @RawRes
, @PluralsRes
, @MenuRes
,
@NavigationRes
, @FontRes
, @FractionRes
, @BoolRes
, @ArrayRes
, @AttrRes
, @AnimatorRes
, @AnimRes
@ColorInt, @ColorLong
表示目标类型为ARGB Color.
示例:
public abstract void setTextColor(@ColorInt int color);
public void setFillColor(@ColorLong long color);
@Dimension
表示目标类型为尺寸类型.
示例:
@Dimension(unit = DP)
public int getDesiredHeight() {
return mDesiredHeight;
}
@Px
等价于@Dimension(unit = PX)
.
@IntRange, @FloatRange
表示值的范围, 不符合会生成警告.
示例:
fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}
from, to参数可以仅指定一个.
@Size
表示集合或数组的大小.
可以指定以下参数:
- @Size(min=1) 最小值
- @Size(max=2) 最大值
- @Size(multiple=2) 倍数
- @Size(2) 准确值
@HalfFloat
表示short类型/short数组存储半精度16位浮点数, 详见android.util.Half
.
@CheckResult
表示调用方应检查返回值.
常用于难以区分纯函数/修改自身的函数的情况, 例如:
public @CheckResult String trim(String s) { return s.trim(); }
s.trim(); // this is probably an error
s = s.trim(); // ok
@CallSuper
表示重写方法应调用super.
示例:
@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
}
线程
表示目标方法/目标类中全部方法需要从指定线程调用.
@MainThread
主线程
@UiThread
UI线程. 一般情况下与主线程相同, 如果有位于非主线程的View, 则可能表示其他线程.
@WorkerThread
工作线程
@BinderThread
Binder线程
@AnyThread
任意线程, 调用时无需考虑所在线程
@GuardedBy
表示目标方法或属性在访问时需持有指定锁.
示例:
final Object objectLock = new Object();
@GuardedBy("objectLock")
volatile Object object;
Object getObject() {
synchronized (objectLock) {
if (object == null) {
object = new Object();
}
}
return object;
}
@Discouraged
表示目标不鼓励使用, 比@Deprecated程度要轻.
示例:
@Discouraged(message = "It is much more efficient to retrieve "
+ "resources by identifier than by name.")
public void getValue(String name) {
...
}
@DoNotInline
表示方法不要内联. 生效于混淆规则:
-keepclassmembers,allowobfuscation class * {
@androidx.annotation.DoNotInline <methods>;
}
@Keep
表示目标应在编译时保留. 生效于混淆规则:
-keep,allowobfuscation @interface androidx.annotation.Keep
-keep @androidx.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <init>(...);
}
可用于防止POJO类型混淆.
@RestrictTo
限制访问范围.
- @RestrictTo(RestrictTo.Scope.SUBCLASSES) 子类
- @RestrictTo(RestrictTo.Scope.LIBRARY) 库
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 相同GroupID
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) 相同Group前缀
- @RestrictTo(RestrictTo.Scope.TESTS) 测试, 等价于 @VisibleForTesting(otherwise = VisibleForTesting.NONE)
@VisibleForTesting
表示目标可见性大于本应具有的可见性, 扩大可见性的原因是用于测试. 参数为本应具有的可见性.
示例:
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun myMethod() {
...
}
@DisplayContext, @UiContext, @NonUiContext
@DisplayContext表示目标context是DisplayContext, 即可以用于getDisplay
.
@UiContext表示目标context是UiContext, 即目标是DisplayContext, 并且可以用于获取UI相关服务(WindowManager, LayoutInflater, WallpaperManager).
@NonUiContext表示目标不是UiContext.
@IntDef, @StringDef
用于创建一个约束值注解, 常用于替代枚举.
示例:
@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();
@GravityInt
表示目标int类型为Gravity, 详见android.view.Gravity
.
应该等价于
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {
Gravity.FILL,
Gravity.FILL_HORIZONTAL,
Gravity.FILL_VERTICAL,
Gravity.START,
Gravity.END,
Gravity.LEFT,
Gravity.RIGHT,
Gravity.TOP,
Gravity.BOTTOM,
Gravity.CENTER,
Gravity.CENTER_HORIZONTAL,
Gravity.CENTER_VERTICAL,
Gravity.DISPLAY_CLIP_HORIZONTAL,
Gravity.DISPLAY_CLIP_VERTICAL,
Gravity.CLIP_HORIZONTAL,
Gravity.CLIP_VERTICAL,
Gravity.NO_GRAVITY
})
public @interface GravityFlags {}
@RequiresApi
表示目标需要具有指定或更高的API等级才能调用, 类似于android.annotation.TargetApi
.
示例:
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public void cubicToPoint(...);
@ChecksSdkIntAtLeast
表示目标方法/属性将检查ApiLevel.
示例:
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O)
public static boolean isAtLeastO() {
return Build.VERSION.SDK_INT >= 26;
}
void foo() {
if (isAtLeastO()) {
// call @RequiresApi(>=26) and no warning.
}
}
@RequiresPermission
表示调用方需具有指定权限.
示例:
@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public abstract void setWallpaper(Bitmap bitmap);
@RequiresPermission(allOf = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_MEDIA_LOCATION})
public static final void copyImageFile(String dest, String source) {
//...
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH)
public static final String ACTION_REQUEST_DISCOVERABLE =
"android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
@RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
@RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
@ContentView
表示目标构造函数接受一个LayoutRes参数, 并将设置为自身布局.
示例:
@ContentView
public Fragment(@LayoutRes int contentLayoutId) {
this();
mContentLayoutId = contentLayoutId;
}
@RequiresFeature
表示调用方应具有目标特性.
示例:
@RequiresFeature(PackageManager.FEATURE_BLUETOOTH)
public final class BluetoothManager {
...
}