Android中通過註解代替findViewById方法

來源:互聯網
上載者:User

標籤:android   c   style   class   blog   code   

轉自:http://www.2cto.com/kf/201405/302998.html

這篇文章主要講解註解實現findViewById的功能,首先我們來熟悉一下在java中怎麼定義一個註解和解析一個註解

註解的概念是在jdk5.0中提出來的,在java.lang的包中已經定義了三個註解:Override,Deprecated,SuppressWarnings
Override相信大家非常熟悉,就是表明這個方法是改寫了父類的方法
Deprecated表示在新版本的 jdk中已經不建議使用這個方法或者屬性
SuppressWarning就是屏蔽掉一些警告

知道了註解的概念後,我們就來自訂註解

註解的定義和介面的介面非常像,在interface的前面多了一個@

public @interface TestPerson{ }

千萬不能把前面的@符號弄掉了,弄掉了就成了介面的定義了,上面是一個最簡單註解的定義,當然註解和類一樣,也可以定義屬性,如下:

public @interface TestPerson{  //name既是這個註解的屬性,也是註解的方法,調用name()傳回值就是name  String name() default gavin;}

我現在想定義兩個註解,一個註解用來說明某個類的意義,另一個註解用來說明類中的某個方法由誰測試的,便於追究責任,定義如下:

//用來標註某個類是用來幹嘛的public @interface ClassFunction{  String value() default ;} //用來標註類中的方法是被誰測試的public @interface TestPerson{  //name是屬性而不是方法,gavin是它的預設值,在定義的時候可以不用給定預設值  String name() default gavin;}

那麼怎麼限定一個註解是用在類上還是用在方法上?比如Override就是用在方法上的註解,Deprecated是既可以用在方法上面,也可以用在類上面,我們直接看看Override是怎麼實現的吧

@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)public @interface Override {} @Documented@Retention(RetentionPolicy.RUNTIME)@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})public @interface Deprecated {}

我們發現這兩個註解在已定義流程中都使用了其他的註解,像Target和Retention這種註解叫做元註解,我們分別看看它們的意思吧
Target註解的功能就是表明你這個註解是用在什麼地方的,它的值是一個枚舉型
 1.CONSTRUCTOR:用於描述構造器
 2.FIELD:用於描述域
 3.LOCAL_VARIABLE:用於描述局部變數
 4.METHOD:用於描述方法
 5.PACKAGE:用於描述包
 6.PARAMETER:用於描述參數
 7.TYPE:用於描述類、介面(包括註解類型) 或enum聲明


Retention註解的功能差不多說明的就是你的註解的生命週期吧,就是什麼時候失效,它的值如下
1.SOURCE:在源檔案中有效(即源檔案保留)
2.CLASS:在class檔案中有效(即class保留)
3.RUNTIME:在運行時有效(即運行時保留)

我就介紹這兩個元註解吧,其他的感覺也用的不是很多,如果你感興趣可以自己Google一下

那麼我們就完善我們自己的註解吧

@Target(ElementType.METHOD)//作用於方法@Retention(RetentionPolicy.RUNTIME)//在運行時有效(即運行時保留)public @interface TestPerson{  //name是屬性而不是方法,gavin是它的預設值,在定義的時候可以不用給定預設值  String name() default gavin;} @Target(ElementType.TYPE)//作用於類上@Retention(RetentionPolicy.RUNTIME)//在運行時有效(即運行時保留)public @interface ClassFunction{  String value() default ;}

那麼我們就來使用一下我們的註解吧

@ClassFunction(用於描述一個人的基本資料)public class Person{  private static final String TAG = Person;     @TestPerson(name=jj)  public void setName()  {       }}

這裡要說明一點就是:如果某個註解屬性使用value作為名稱如ClassFunction中的value,那麼賦值的時候可以直接@ClassFunction(用於描述一個人的基本資料),但是如果你使用的是其他名稱,那麼必須@TestPerson(name=jj)這樣調用

以上就是定義一個註解的過程,下面我們來解析一個註解
定義一個TestPerson註解

/** * com.annotation.TestPerson * @author yuanzeyao   * create at 2014年5月21日 下午1:30:14 */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface TestPerson {     String name();}

然後在Person類中加入註解

public class Person {  private static final String TAG = Person;  @TestPerson(name=gavin)  public void getName()  {       }}

解析註解

public class Main {  private static final String TAG = Main;  public static void main(String[] args)   {     Person person=new Person();     //獲得Person對應的Class     Class<person> clazz=Person.class;     try {      //找到getName方法      Method method=clazz.getMethod(getName,null);      //判斷是否被TestPerson標註      if(method.isAnnotationPresent(TestPerson.class))      {        //調用getName方法        method.invoke(person, null);        //得到TestPerson註解的執行個體        TestPerson test=method.getAnnotation(TestPerson.class);        //獲得其name屬性        String name=test.name();        System.out.println(this method is test by-->+name);      }    } catch (SecurityException e) {    } catch (NoSuchMethodException e) {    } catch (IllegalArgumentException e) {    } catch (IllegalAccessException e) {    } catch (InvocationTargetException e) {    }  }}

已經將定義註解和解析註解講解完了,下面來具體分析一下怎麼在Android中使用註解來代替findViewById
定義一個註解

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface InjectView {  //id就是控制項id,在某一個控制項上使用註解標註其id  int id() default -1;}

在Activity中加入註解

public class MainActivity extends Activity {  public static final String TAG=MainActivity;  //標註TextView的id  @InjectView(id=R.id.tv_img)  private TextView mText;     @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    try {      autoInjectAllField(this);    } catch (IllegalAccessException e) {    } catch (IllegalArgumentException e) {    }         if(mText!=null)      mText.setText(Hello Gavin);  }     public void autoInjectAllField(Activity activity) throws IllegalAccessException, IllegalArgumentException  {    //得到Activity對應的Class    Class clazz=this.getClass();    //得到該Activity的所有欄位    Field []fields=clazz.getDeclaredFields();    Log.v(TAG, fields size-->+fields.length);    for(Field field :fields)    {      //判斷欄位是否標註InjectView      if(field.isAnnotationPresent(InjectView.class))      {        Log.v(TAG, is injectView);        //如果標註了,就獲得它的id        InjectView inject=field.getAnnotation(InjectView.class);        int id=inject.id();        Log.v(TAG, id--->+id);        if(id>0)        {          //反射訪問私人成員,必須加上這句          field.setAccessible(true);          //然後對這個屬性複製          field.set(activity, activity.findViewById(id));        }      }    }  }   }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.