歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

Android學(xué)習(xí)之注解的使用詳解

發(fā)布時間:2017-09-19 23:08  回復(fù):0  查看:3051   最后回復(fù):2017-09-19 23:08  
Android Support Library  從  19.1  版本開始引入了一個新的注解庫,其中包含了很多的元注解,使用它們修飾我們的代碼, 可以讓我們提高程序的開發(fā)效率,讓我們更早的發(fā)現(xiàn)問題。以及對代碼施以規(guī)范,讓代碼更加有可讀性。本文和大家 簡單介紹了 下這些注解,以及其使用,一起來看看吧,希望對大家 學(xué)習(xí)android有所幫助。
  注:現(xiàn)在我們新建項目直接就依賴了 support.appcompat  包,其中已經(jīng)依賴了  annotations  包。如果你的項目中寫如下注解報錯,可以添加注解包:
   dependencies {
   compile 'com.android.support:support-annotations:22.2.0'
  }
   @IntDef & @StringDef
  替代 Java  中枚舉的注解,以  @IntDef  為例,定義和使用如下:
@IntDef({RED, BLUE, YELLOW})
@Retention(RetentionPolicy.SOURCE)
public @interface LightColors{};
public  static  final  int RED = 1;
public  static  final  int BLUE = 2;
public  static  final  int YELLOW = 3;
   public  void  setColor(@LightColors  int color){
  }
  · @interface :聲明新的枚舉注解類型。
  · @Retention(RetentionPolicy.SOURCE) :告知編譯器不將枚舉的注解數(shù)據(jù)存儲在  .class  文件中。
  如果允許常量與標(biāo)志(例如:| 、 和  等等)相結(jié)合,則我們可以使用  flag  屬性,如:
  @IntDef(flag = true,  value = {RED, BLUE, YELLOW})
  使用:
  setColor( RED | BLUE);
   @Nullable & @NonNull
  · @Nullable :注解的元素可以為  null
  · @NonNull :注解的元素不可以為  null 。
  上面的注解可以修飾如下元素:
  1 ,方法參數(shù)。如:
  @Nullable private String  data;
  2 ,方法的返回值。 如:
  @Nullable public String getData(){
   return  data;
  }
  3 ,成員屬性。如:
   public  void  setData(@Nullable String data){
  }
  當(dāng)用空的參數(shù)傳給被 @NonNull  修飾的方法參數(shù)的方法時,會給出如下警告提示(編譯不會報錯):
  passing "null"  argument  to parameter annotated  as @NotNull
   @FloatRange & @IntRange
  @FloatRange  和  @IntRange  是用于限定范圍的注解。其中  @FloatRange  是限定  float  類型的,而  @IntRange  是限定 int  類型的。它們同上注解一樣,可以修飾方法參數(shù)、方法返回值、成員屬性。
  以 @IntRange  為例,修飾方法參數(shù)的定義如下:
   public  void  setAge(@IntRange(from = 1, to = 180) int age){
  }
  如果調(diào)用該方法傳的參數(shù)不在 1 - 180  的范圍內(nèi), 如: setAge(0) ,那么編譯會直接報如下錯:
  value must  be ≥ 1 and ≤ 180 (was 0)
   @Size
  @Size  注解的作用是限定長度的,同上注解一樣,可以修飾方法參數(shù)、方法返回值、成員屬性。
  ·  限定字符串的長度:
   public  void  setData(@Size(4) String data){
  }
    當(dāng)傳入的字符串長度不等于 4  時,編譯器會直接報錯:
   Length must be exactly 4
  ·  限定數(shù)組的長度:
   public  void  setData(@Size(4) int[] data){
  }
    特殊的限定,如限定為 2  的倍數(shù):
   public  void  setData(@Size(multiple = 2) int[] data){
  }
  ·  限定最小的長度:
  @Size(min = 2)
  ·  限定最大的長度:
  @Size(max = 2)
    等同于  @Size(2)  寫法:
  @Size(value = 2)
   @RequiresPermission
  該注解作用是表明方法所執(zhí)行的內(nèi)容需要權(quán)限。如需要單個權(quán)限:
  @ RequiresPermission( Manifest. permission. CALL_PHONE)
  private void callPhone(String phone){
  }
  需要一組權(quán)限:
  @RequiresPermission(allOf = {
  Manifest.permission.READ_EXTERNAL_STORAGE,
  Manifest.permission.WRITE_EXTERNAL_STORAGE})
  public  static  final  void copyFile(String dest, String source) {
  ...
  }
  對于 intent  權(quán)限,我們可以定義在  intent  操作名稱的字符串上:
  @ RequiresPermission( android. Manifest. permission. BLUETOOTH)
  public static final String ACTION_REQUEST_DISCOVERABLE =
  "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
  對于需要單獨讀寫權(quán)限的內(nèi)容提供程序的權(quán)限,我們可以在 @RequiresPermission.Read  或  @RequiresPermission.Write 注解中包含每個權(quán)限要求:
  @RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))@RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
  public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
  如果權(quán)限依賴于提供給方法參數(shù)的特定值,那么可以對參數(shù)本身使用 @RequiresPermission  而不用列出具體的權(quán)限,如  startActivity(intent)  方法:
   public  abstract  void  startActivity(@RequiresPermission Intent intent, @Nullable Bundle) {...}
  當(dāng)我們使用這種方式(間接權(quán)限)時,構(gòu)建工具將執(zhí)行數(shù)據(jù)流分析以檢查傳遞到方法的參數(shù)是否具有任何@RequiresPermission  注解。如:
  Intent intent =  new Intent(Intent.ACTION_CALL);
  intent.setData(Uri.parse("tel:1234567890"));
  startActivity(intent);
  這里的 startActivity(intent)  就直接報錯了:
   call requires permission which may be rejected  by  user: code should explicitly  check  to see  if permission  isavailable ( with `checkPermission`)  or explicitly handle a potential `SecurityException`
  因為 Intent.ACTION_CALL  中標(biāo)記了權(quán)限注解:
  @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)@RequiresPermission(Manifest.permission.CALL_PHONE)
  public static final String ACTION_CALL = "android.intent.action.CALL";
   @CheckResult
  @CheckResult  注解是作用于方法上的,作用是檢驗有沒有處理返回值。如果沒有處理返回值則會報錯。
  @CheckResult public String getData(String  data) {
   return  data.trim();
  }
   線程注解
  線程注解可以檢查某個方法是否從特定類型的線程調(diào)用。支持以下線程注解:
  ·@MainThread :表示標(biāo)記的方法只應(yīng)在主線程調(diào)用。如果標(biāo)記的是一個類,那么該類中的所有方法都應(yīng)該是在主線程被調(diào)用。例:(通常,應(yīng)用程序的主線程也是  Ui  線程。但是,在特殊情況下,應(yīng)用程序的主線程可能不是其  Ui  線程)
  @MainThread public  void  deliverResult(D data) { ... }
  ·@UiThread :表示標(biāo)記的方法或構(gòu)造函數(shù)只應(yīng)該在  Ui  線程上調(diào)用。如果標(biāo)記的是一個類,那么該類中的所有方法都應(yīng)是在  Ui  線程被調(diào)用。例:
  @UiThread
  public abstract void setText(@NonNull String text) {...}
  ·@WorkerThread :表示標(biāo)記的方法只應(yīng)該在工作線程上調(diào)用。如果標(biāo)記的是一個類,那么該類中的所有方法都應(yīng)是在一個工作線程上調(diào)用。例:
  @WorkerThread protected  abstract FilterResults  performFiltering(CharSequence constraint);
  ·@BinderThread :表示標(biāo)記的方法只應(yīng)在綁定線程上調(diào)用。如果標(biāo)記的是一個類,那么該類中的所有方法都應(yīng)是在綁定線程被調(diào)用。例:
  @BinderThread public BeamShareData  createBeamShareData() { ... }
  ·@AnyThread :表示可以從任何線程調(diào)用帶標(biāo)記的方法。如果標(biāo)記的是一個類,那么該類中的所有方法都可以從任何線程中調(diào)用。例:
  @AnyThread public  void  deliverResult(D data) { ... }
  構(gòu)建工具會將 @MainThread  和  @UiThread  注解視為可以互換,因此,我們可以從  @MainThread  方法調(diào)用  @UiThread 方法,反之亦然。不過如果系統(tǒng)應(yīng)用在不同線程上帶有多個試圖, Ui  線程可與主線程不同。因此,我們應(yīng)該使用  @UiThread 標(biāo)注于應(yīng)用的視圖層次結(jié)構(gòu)關(guān)聯(lián)的方法,使用  @MainThread  僅標(biāo)注于應(yīng)用生命周期關(guān)聯(lián)的方法。
   資源注解
  在 Android  中幾乎所有的資源都有其對于的  id ,我們在使用的時候可以直接通過  id  來,如:
   textView.setText( getResources().getText( R.string.app_name));
  但是這樣如果沒有寫指定的資源注解的話就會風(fēng)險,比如隨便傳了個 0 ,那么就會找不到對應(yīng)的資源。
  為了避免由于自己的粗心大意而引發(fā)的錯誤,我們就可以使用資源注解了,如:
   public  int  getText(@StringRes int id){
  }
  這樣當(dāng)我們調(diào)用該方法時,如果傳遞的參數(shù)并不是 String  類型的資源  id ,那么編譯器就會報錯提示。
  除了  @StringRes  資源注解外,還有:
  · @IntegerRes R.integer  類型資源。
  · @AnimatorRes R.animator  類型資源。
  · @AnimRes R.anim  類型資源。
  · @ArrayRes R.array  類型資源。
  · @AttrRes R.attr  類型資源。
  · @BoolRes R.bool  類型資源。
  · @ColorRes R.color  類型資源。
  · @DimenRes R.dimen  類型資源。
  · @DrawableRes R.drawable  類型資源。
  · @FractionRes R.fraction  類型資源。(百分比)
  · @IdRes R.id  類型資源。
  · @InterpolatorRes R.interpolator  類型資源。(插值器)
  · @LayoutRes R.layout  類型資源。
  · @MenuRes R.menu  類型資源。
  · @PluralsRes R.plurals  類型資源。(復(fù)數(shù))
  · @RawRes R.raw  類型資源。
  · @StyleableRes R.styleable  類型資源。
  · @StyleRes R.style  類型資源。
  · @TransitionRes :  R.transition  類型資源。
  · @XmlRes R.xml  類型資源。
  · @AnyRes :未知資源。(表示自己不知道是什么類型的資源。比如有可能為  R.drawable  也有可能是  R.string 。)
   @ColorInt
  @ColorInt  注解的作用為:限定顏色值。( ARGB 0xAARRGGBB
   public  void  setColor(@ColorInt int color) {
  }
  如果直接使用資源 id ,則會報錯,如下:
   setColor(R.color.colorAccent)//  報錯
  正確的使用是:
   setColor(0xFFFF00FF);
  如果要使用資源 id ,則可以通過  ContextCompat.getColor()  方法來:
  setColor( ContextCompat.getColor( context, R.color.colorAccent));
   @CallSuper
  該注解用于修飾方法,表示重寫該方法時必須調(diào)用 super  方法。如  onCreate()  方法:
  @CallSuper protected  void  onCreate(Bundle savedInstanceState) {
  }
  重寫 onCreate()  方法時,必須調(diào)用  super  方法:
   super.onCreate(savedInstanceState);
  否則報錯。
   @VisibleForTesting & @Keep
  使用 @VisibleForTesting  和  @Keep  注解可以表示方法、類、或字段的可訪問性。
  · @VisibleForTesting : 標(biāo)記的指定代碼在測試時是否可見。
  · @Keep :標(biāo)記的指定代碼在混淆時不會被混淆。
來源: 稀土掘金
您還未登錄,請先登錄

熱門帖子

最新帖子

?