@Nullable, @NonNull
用于修饰变量/参数/返回值. @Nullbale表示可空, @NonNull表示非空.
以下行为会生成警告:
将null/可空值赋值给非空变量/参数/字段
未进行null检查而直接调用可空值的方法/字段
此外, null注解也作用于Kotlin于Java交互:
1 2
| @NonNull String foo(@Nullable String a, @NonNull String b) {}
|
对应Kotlin函数签名:
1
| fun foo(a: String?, b: String): String
|
Resource ID
表示目标资源ID的类型.
任意类型资源ID: @AnyRes
示例:
1
| 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.
示例:
1 2 3
| public abstract void setTextColor(@ColorInt int color);
public void setFillColor(@ColorLong long color);
|
@Dimension
表示目标类型为尺寸类型.
示例:
1 2 3 4
| @Dimension(unit = DP) public int getDesiredHeight() { return mDesiredHeight; }
|
@Px
等价于@Dimension(unit = PX)
.
@IntRange, @FloatRange
表示值的范围, 不符合会生成警告.
示例:
1
| 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
表示调用方应检查返回值.
常用于难以区分纯函数/修改自身的函数的情况, 例如:
1 2 3 4
| public @CheckResult String trim(String s) { return s.trim(); }
s.trim(); s = s.trim();
|
@CallSuper
表示重写方法应调用super.
示例:
1 2 3
| @CallSuper override fun onCreate(savedInstanceState: Bundle?) { }
|
线程
表示目标方法/目标类中全部方法需要从指定线程调用.
@MainThread
主线程
@UiThread
UI线程. 一般情况下与主线程相同, 如果有位于非主线程的View, 则可能表示其他线程.
@WorkerThread
工作线程
@BinderThread
Binder线程
@AnyThread
任意线程, 调用时无需考虑所在线程
@GuardedBy
表示目标方法或属性在访问时需持有指定锁.
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| final Object objectLock = new Object();
@GuardedBy("objectLock") volatile Object object;
Object getObject() { synchronized (objectLock) { if (object == null) { object = new Object(); } } return object; }
|
@Discouraged
表示目标不鼓励使用, 比@Deprecated程度要轻.
示例:
1 2 3 4 5
| @Discouraged(message = "It is much more efficient to retrieve " + "resources by identifier than by name.") public void getValue(String name) { ... }
|
@DoNotInline
表示方法不要内联. 生效于混淆规则:
1 2 3
| -keepclassmembers,allowobfuscation class * { @androidx.annotation.DoNotInline <methods>; }
|
@Keep
表示目标应在编译时保留. 生效于混淆规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| -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
表示目标可见性大于本应具有的可见性, 扩大可见性的原因是用于测试. 参数为本应具有的可见性.
示例:
1 2 3 4
| @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
用于创建一个约束值注解, 常用于替代枚举.
示例:
1 2 3 4 5 6 7 8 9 10 11 12
| @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
.
应该等价于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @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
.
示例:
1 2
| @RequiresApi(Build.VERSION_CODES.LOLLIPOP) public void cubicToPoint(...);
|
@ChecksSdkIntAtLeast
表示目标方法/属性将检查ApiLevel.
示例:
1 2 3 4 5 6 7 8 9 10
| @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O) public static boolean isAtLeastO() { return Build.VERSION.SDK_INT >= 26; }
void foo() { if (isAtLeastO()) { } }
|
@RequiresPermission
表示调用方需具有指定权限.
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @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参数, 并将设置为自身布局.
示例:
1 2 3 4 5
| @ContentView public Fragment(@LayoutRes int contentLayoutId) { this(); mContentLayoutId = contentLayoutId; }
|
@RequiresFeature
表示调用方应具有目标特性.
示例:
1 2 3 4
| @RequiresFeature(PackageManager.FEATURE_BLUETOOTH) public final class BluetoothManager { ... }
|