Support Annotation Library 是提供了一系列元注解,用來幫助開發(fā)者在編譯期間發(fā)現(xiàn)可能存在的BUG.
1. Nullness 注解
此類注解包含 :
- @Nullable 作用于函數(shù)參數(shù)和返回值,標(biāo)記參數(shù)或者返回值可以為空.
- @NonNull 作用于函數(shù)參數(shù)和返回值,標(biāo)記參數(shù)或者返回值不可以為空.
Android Studio 會自動提示注解錯誤.
2. 資源類型注解
在Android中資源通常用整形值表示,保存在R文件中. 這樣存在的問題就是如果一個需要使用Layout資源的地方傳入了一個String類型的資源編譯期間也不會報(bào)錯,只有在運(yùn)行到相應(yīng)代碼時(shí)才會發(fā)現(xiàn)錯誤. 使用資源型注解就可以解決這個問題.
注解符號 | 標(biāo)記類型 |
---|---|
@AnimatorRes | android.R.animator |
@AnimRes | android.R.anim |
@AnyRes | 標(biāo)記整形值是任意一種資源 |
@ArrayRes | android.R.array |
@AttrRes | android.R.attr |
@BoolRes | 整形值是布爾類型 |
@ColorRes | android.R.color |
@Drawable | android.R.drawable |
@IdRes | android.R.id |
@FracriionRes | fraction類型,這種比較少見,這種資源類型常見于Animation XML中. |
@IntegerRes | android.R.layout |
@InterpolatorRes | android.R.interpolator |
@LayoutRes | android.R.layout |
@MenuRes | android.R.menu |
@PluralsRes | android.R.plurals 表示復(fù)數(shù)字符串. |
@RawRes | android.R.raw |
@StringRes | android.R.string |
@StyleableRes | android.R.styleable |
@StyleRes | android.R.style |
@TransitionRes | 標(biāo)記 transition類型 |
@XmlRes | android.R.xml |
3. 類型定義注解
在Android開發(fā)中,整數(shù)值不僅用來代表資源值,也經(jīng)常用來代表枚舉值. 使用@IntDef 注解可以定義一個新的整形類型的注解.
用法一 : 定義范圍
// 定義可以接收的常量列表.
@IntDef({X_1,X_2,X_3})
// 定義注解.
public @interface TestMode {}
// 定義常量
public final static int X_1 = 0x01;
public final static int X_2 = 0x02;
public final static int X_3 = 0x03;
// 使用定義的注解, 如果mode不是三個常量之一Android Studio會給出警告.
public void setTestMode(@TestMode int mode){
}
@TestMode
public int getTestMode(){
return X_1;
}
// 使用
public void test(){
setTestMode(X_1);
}
用法二 : 定義一個flag標(biāo)志位,來識別函數(shù)參數(shù)或者返回值是否符合某一種模式.
// 定義范圍
@IntDef(flag = true, value = {
XX_1,XX_2,XX_3
})
// 定義注解
public @interface TestMode2 {}
// 定義常量
public static final int XX_1 = 0x01;
public static final int XX_2 = XX_1 << 1;
public static final int XX_3 = XX_1 << 2;
// 使用
@TestMode2
public int getMode2(){
return XX_1;
}
public void setMode2(@TestMode2 int mode2){
}
public void test2(){
// 這種模式下可以使用多個并在一起
setMode2(XX_1 | XX_3);
}
4. 線程注解
- @UiThread : 標(biāo)記運(yùn)行在UI線程.
- @MainThread : 運(yùn)行在主線程,一個應(yīng)用只有一個主線程,主線程也是@UIThread線程,通常情況下我們可以使用@MainThread 來注解生命周期相關(guān)的函數(shù),使用@UiThread 來注解視圖相關(guān)的函數(shù),一般情況下兩者可以互換.
- @WorkerThread : 標(biāo)記運(yùn)行在后臺線程.
- @BinderThread : 標(biāo)記運(yùn)行在Binder線程中.
@UiThread
public void testUiThread(){
Log.d(TAG,"運(yùn)行在UI線程中");
}
@MainThread
public void testMainThread(){
Log.d(TAG, "運(yùn)行在主線程");
}
@WorkerThread
public void testWorkerThread(){
Log.d(TAG, "運(yùn)行在后臺線程");
}
@BinderThread
public void testBinderThread(){
Log.d(TAG, "運(yùn)行在Binder線程");
}
5. 值范圍注解
當(dāng)函數(shù)取值是一定范圍時(shí),我們可以使用值范圍注解來防止調(diào)用這傳入錯誤參數(shù).
-
@Size : 對于集合赠潦、數(shù)組和字符串之類的參數(shù),開使用@Size注解來表示這些參數(shù)的大小.
- @Size(min=1) // 集合幣可以為空
- @Size(max=4) // 字符串最大字符個數(shù)是4.
- @Size(2) // 數(shù)組元素兩個.
- @Size(multiple=2) //數(shù)組大小是2 的倍數(shù).
// 數(shù)組不能為空
public void testRange1(@Size(min = 1) final byte[] bbs){
}
// 數(shù)組長度大4
public void testRange2(@Size(max = 4) final byte[] bbs){
}
// 兩個字符
public void testRange3(@Size(2) String string){
}
// 長度是 2 的倍數(shù).
public void testRange4(@Size(multiple = 2) String string){
}
- @IntRange : 參數(shù)可以是 int 或者 long
// 0-255
public void testRange5(@IntRange(from = 0,to = 255) int alpha){
}
- @FloatRange : 參數(shù)是float或者double
// 0.0-255.0
public void testRange6(@FloatRange(from = 0.0,to = 255.0) float alpha){
}
6. 權(quán)限注解
Android 應(yīng)用在使用某些系統(tǒng)功能時(shí),需要在AndroidManifest.xml中聲明權(quán)限,否則運(yùn)行會報(bào)錯. 使用權(quán)限注解@RequiresPermission 可以幫助我們在編譯時(shí)找出錯誤.
- 需要聲明一個權(quán)限
// 調(diào)用此方法需要聲明權(quán)限.
@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public void testPermissionAnnotation() {
}
- 需要聲明集合中的至少一個權(quán)限
// 調(diào)用此方法需要聲明下面任何一個權(quán)限.
@RequiresPermission(anyOf = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION})
public void testPermission2(){}
- 需要聲明集合中的所有權(quán)限
// 調(diào)用此方法需要聲明下面所有的權(quán)限.
@RequiresPermission(allOf = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION})
public void testPermission3(){}
- Intent 調(diào)用所需權(quán)限,可以在Intent的ACTION字符串定義處添加注解
// Intent 的這個Action需要使用如下權(quán)限
@RequiresPermission(Manifest.permission.EXPAND_STATUS_BAR)
public static final String ACTION_MY = "custom_action";
- ContentProvider 同時(shí)需要讀寫
// 對于ContentProvider
@RequiresPermission.Read(@RequiresPermission(Manifest.permission.READ_CALENDAR))
@RequiresPermission.Write(@RequiresPermission(Manifest.permission.READ_CALENDAR))
public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
7. 重寫函數(shù)注解
如果API允許重寫某個函數(shù),但同時(shí)要求重寫的函數(shù)調(diào)用被重寫函數(shù)則可以使用@CallSuper注解.
@CallSuper
public static int testCallSuper() {
return 0;
}
8. 返回值注解
需要調(diào)用者對返回值進(jìn)行某些處理,可以使用@CheckResult 回調(diào). suggest 會是提示內(nèi)容.
@CheckResult(suggest = "檢查一下返回值唄")
public static int testReturn(){
return 12;
}
public static void testCheck(){
int x = testReturn();
}
9. 單元測試 @VisibaleForTesting
使某些變量在單元測試中可見.
10. @Keep
用來標(biāo)記在混淆時(shí)不需要混淆的方法.
參考 : Android 高級進(jìn)階