0%

AndroidX注解

@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(); // this is probably an error
s = s.trim(); // ok

@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()) {
// call @RequiresApi(>=26) and no warning.
}
}

@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 {
...
}