Android註解支持(Support Annotations)

原文地址:http://tools.android.com/tech-docs/support-annotations

Android Support Library從19.1版本開始引入了一個新的註解庫,其中包括了很多有用的元註解,可以用來修飾代碼並且幫助發現bug。Support Library本身也使用了這些註解,當使用Support Library庫的時候,Android Studio實際上已經在基於這些註解來檢查代碼中的潛在問題了。

使用註解庫

這些註解不是默認加載的,它們被包裝爲一個單獨的庫。Support Library現在是由一些更小的庫組成的,包括:v4-support、appcompat、gridlayout、mediarouter等等。

添加註解的最簡單的方法就是打開Project Structure對話框。首先在左邊選中module,然後右邊選中Dependencies標籤,點擊“+”號按鈕,選擇Library Dependency。如果SDK中已經包括了Android Support庫,那麼註解支持庫就會顯示在快捷選擇列表中了,只需要點擊選擇就可以。

步驟1:點擊Project Structure按鈕



步驟2:選中Dependencies標籤,點擊“+”號按鈕


步驟3:在下拉列表中選中support-annotations庫


點擊OK確定,這將會修改build.gradle文件。當然也可以手動在Gradle中添加如下依賴:
dependencies {
    compile 'com.android.support:support-annotations:20.0.0'
}

Nullness註解

@Nullable註解可以用來標識特定的參數或者返回值可以爲null。
類似的,@NonNull註解可以用來標識參數不能爲null。

如果一個局部變量已經被知道爲null,然後它被作爲參數傳遞給了一個方法,並且這個參數被標記爲@NonNull,那麼IDE會警告這樣做可能引發潛在的Crash問題。

v4 support library中的示例代碼:
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
...
    
    /**
     * Add support for inflating the <fragment> tag.
     */
    @Nullable
    @Override
    public View onCreateView(String name, @NonNull Context context, @NonNull AttributeSet attrs) {
        ...

Resource Type Annotations(資源類型註解)

資源在Android中作爲整型值來傳遞。這意味着希望獲取一個drawable作爲參數的代碼很容易被傳遞了一個string類型的資源,因爲他們資源id都是整型的,編譯器很難區分。

Resource Type Annotations在這種條件下可以提供類型檢查。例如,對一個int型參數添加@StringRes註解,如果傳遞的不是R.string類型的引用都會被編譯器標記。

ActionBar的例子
import android.support.annotation.StringRes;
...
    public abstract void setTitle(@StringRes int resId);

IntDef/StringDef: Magic Constant Annotations(常量註解)

int型除了被作爲資源引用傳遞之外,還經常被作爲一種“枚舉”類型來使用。
@IntDef註解讓你可以實現一種類似於"typedef"的效果,你可以在創建一個註解的同時列出所有可用的有效值,然後再使用這個註解。也就是說@IntDef是用來修飾註解的註解(元註解),用它所修飾的註解在使用時就限定了被修飾對象的可取值範圍。
來看以下appcompat 庫中實際的例子:
import android.support.annotation.IntDef;
...
public abstract class ActionBar {
    ...
    @Retention(RetentionPolicy.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;

    @NavigationMode
    public abstract int getNavigationMode();

    public abstract void setNavigationMode(@NavigationMode int mode);

以上例子中創建了一個新的註解(public @interface NavigationMode)然後我們對這個註解使用了元註解@IntDef,然後列出了所有可能的值(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS),然後我們再用這個註解修飾了一個方法(getNavigationMode()),於是這個方法的返回值就被限定爲NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS這三個枚舉值中的一個了。

使用這個註解後,如果返回值和傳遞的參數值不在枚舉值中,IDE工具就會標記出不符合註解要求的代碼。

還可以通過@IntRef註解指定一個int型變量是一個“flag”類型,“flag”類型意味着它的取值可以是一些常量進行位運算(|、&、^)之後的結果
請看如下註解示例:
@IntDef(flag=true, value={
            DISPLAY_USE_LOGO,
            DISPLAY_SHOW_HOME,
            DISPLAY_HOME_AS_UP,
            DISPLAY_SHOW_TITLE,
            DISPLAY_SHOW_CUSTOM
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface DisplayOptions {}

於是被@DisplayOptions註解修飾的變量可以接受@InfDef列出的值或者這些值相互位運算的結果,例如DISPLAY_USE_LOGO | DISPLAY_SHOW_HOME。

最後,這個註解還有一個String版本的類型——@StringDef,它和@IntDef的使用目的是一樣的,只是對象是String類型的值。這個註解使用的場景並不是很常見,但是卻可以很好地限定允許向Activity#getSystemService方法傳遞的字符串常量的範圍:

(以上註解其實是基於IntelliJ的MagicConstant Annotation,你可以在這裏獲取更爲詳細的信息:http://blog.jetbrains.com/idea/2012/02/new-magic-constant-inspection/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章