注解(Annotations)使用和自定義

本博客是一個純技術(shù)交流博客招盲,寫出來的文章是幫大家解決一些問題溃肪,或讓大家有個參考和思路,更多技術(shù)分享請關(guān)注http://blog.36dr.net痹栖,有任何問題可與我郵件dr.kalen@yahoo.com

前言

Android默認(rèn)提供Annotation框架同時網(wǎng)絡(luò)也沖刺著各種Android Annotation框架瞭空,諸如此類框架很多结耀,但是用過之后使用都比較復(fù)雜留夜,同時還有一些無法避免的bug。如在Android開發(fā)時經(jīng)常會遇到獲得界面中的View使用方法findViewById特別是在Adapter中需要對所有使用的組件變量賦值图甜,每次調(diào)用findViewById就顯得多余的開發(fā)碍粥,若采用注解則會方便開發(fā),精簡代碼的結(jié)構(gòu)和提示代碼閱讀性黑毅,當(dāng)然由于Annotation是反射機制設(shè)置變量值嚼摩,則在性能上會相對于普通方式差,在此硬件比拼的時代矿瘦,此性能幾乎可以忽略枕面。

原理和自定義

以前言中提到Android開發(fā)多次調(diào)用findViewById方法的困惑,我們通過自定義Annotation來解決此問題缚去。如下:

  1. 定義注解類:
@Target(ElementType.FIELD)//表示用在字段上  
@Retention(RetentionPolicy.RUNTIME)//表示在生命周期是運行時  
public @interface ViewInject {  
    int value() default 0;  //返回注解中的信息
}  
  1. 定義一個BaseActivity作為需要注解的基類潮秘,用于實現(xiàn)注解的功能(反射注入數(shù)據(jù))
public abstract class BaseActivity extends FragmentActivity {  
    /**
     * get content view layout id
     *  
     * @return
     */  
    public abstract int getLayoutId();  


    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(getLayoutId());  
        autoInjectAllField();  
    }  
    /**
     * 解析注解
     */  
    public void autoInjectAllField() {  
        try {  
            Class<?> clazz = this.getClass();  
            Field[] fields = clazz.getDeclaredFields();//獲得Activity中聲明的字段  
            for (Field field : fields) {  
                // 查看這個字段是否有我們自定義的注解類標(biāo)志的  
                if (field.isAnnotationPresent(ViewInject.class)) {  
                    ViewInject inject = field.getAnnotation(ViewInject.class);  
                    int id = inject.value();  
                    if (id > 0) {  
                        field.setAccessible(true);  
                        field.set(this, this.findViewById(id));//給我們要找的字段設(shè)置值  
                    }  
                }  
            }  
        } catch (IllegalAccessException e) {  
            e.printStackTrace();  
        } catch (IllegalArgumentException e) {  
            e.printStackTrace();  
        }  
    }  
}  
  1. 注解使用
public class TestActivity extends BaseActivity {  

    @ViewInject(R.id.claim_statement)  
    private WebView mWebView;  


    @Override  
    public int getLayoutId() {  
        // TODO Auto-generated method stub  
        return R.layout.activity_claim;  
    }  

}  

詳細(xì)說明

系統(tǒng)中方法經(jīng)常會使用@Override和@Deprecated注解,我們看看系統(tǒng)注解如何定義:

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

我們發(fā)現(xiàn)這兩個注解用到了其他注解@Target,@Retention,@Documented易结;這些注解稱之為元注解枕荞。

  1. @Target用于標(biāo)明注解用于的地方,它的值是一個枚舉值:
  • CONSTRUCTOR:用于描述構(gòu)造器
  • FIELD:用于描述域
  • LOCAL_VARIABLE:用于描述局部變量
  • METHOD:用于描述方法
  • PACKAGE:用于描述包
  • PARAMETER:用于描述參數(shù)
  • TYPE:用于描述類搞动、接口(包括注解類型) 或enum聲明
  1. @Retention用于描述注解的生命周期即在什么情況有效躏精,它的值:
  • SOURCE:在源文件中有效(即源文件保留編譯時忽略)
  • CLASS:在class文件中有效(即class保留JVM忽略)
  • RUNTIME:在運行時有效(即運行時保留)
  1. @Documented表明這個注解應(yīng)該被javadoc工具記錄。

因此當(dāng)我們定義的注解中:

@Target(ElementType.FIELD)//表示用在字段上  
@Retention(RetentionPolicy.RUNTIME)//表示在生命周期是運行時  
public @interface ViewInject {  
    int value() default 0;  //返回注解中的信息

    String name() default "default name"
}  

就很好解釋了鹦肿,ViewInject注解是用于變量并且運行時有效矗烛,用于獲得注解中的內(nèi)容,內(nèi)容信息為int并且默認(rèn)為0.

注解類中方法value()表示獲取注解中默認(rèn)文字比如@ViewInject(R.id.name)獲取的R.id.name的值箩溃,如果是name或則其他方法瞭吃,則表示需要在注解中使用屬性才能獲取。及獲取@ViewInject(name="name")中的name屬性值涣旨。

由此虱而,我們可以根據(jù)自己喜好,自己的功能需要开泽,自定義合適項目的注解和注解的解析方式牡拇。
Android 注解請學(xué)習(xí)“Android Annotation”框架。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末穆律,一起剝皮案震驚了整個濱河市惠呼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峦耘,老刑警劉巖剔蹋,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辅髓,居然都是意外死亡泣崩,警方通過查閱死者的電腦和手機少梁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來矫付,“玉大人凯沪,你說我怎么就攤上這事÷蛴牛” “怎么了妨马?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長杀赢。 經(jīng)常有香客問我烘跺,道長,這世上最難降的妖魔是什么脂崔? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任滤淳,我火速辦了婚禮,結(jié)果婚禮上砌左,老公的妹妹穿的比我還像新娘脖咐。我一直安慰自己,他們只是感情好绊困,可當(dāng)我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布文搂。 她就那樣靜靜地躺著适刀,像睡著了一般秤朗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笔喉,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天取视,我揣著相機與錄音,去河邊找鬼常挚。 笑死作谭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奄毡。 我是一名探鬼主播折欠,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吼过!你這毒婦竟也來了锐秦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤盗忱,失蹤者是張志新(化名)和其女友劉穎酱床,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趟佃,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡扇谣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年昧捷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罐寨。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡靡挥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衩茸,到底是詐尸還是另有隱情芹血,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布楞慈,位于F島的核電站幔烛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏囊蓝。R本人自食惡果不足惜饿悬,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望聚霜。 院中可真熱鬧狡恬,春花似錦、人聲如沸蝎宇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姥芥。三九已至兔乞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凉唐,已是汗流浹背庸追。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留台囱,地道東北人淡溯。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像簿训,于是被迫代替她去往敵國和親咱娶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內(nèi)容