android註解使用詳解(圖文),android使用詳解
在使用Java的SSH架構的時候,一直在感歎註解真是方便啊,關於註解的原理,大家可以參考我的另一片文章Java註解詳解。最近有時間研究了android註解的使用,今天與大家分享一下。
android中註解的使用用到了GitHub上的開源架構androidannotations,。這個開源架構應該是目前使用人數最多的android註解架構了,主要是由於它設計的註解標籤非常多,能夠滿足我們日常開發中的大部分需求。androidannotations將許多可以抽取出來的方法都封裝成了註解標籤供我們使用,一會我會給大傢具體示範。
好了,言歸正傳,我們一起來看看怎麼使用這個東東。
第一步
下載androidannotations
下載之後解壓檔案,我們會看到有兩個jar包:
第二步
在eclipse上組態架構:
1.建立一個android項目,把androidannotations-api-3.2.jar拷貝到libs檔案夾中,同時在項目中建立一個檔案夾,叫做compile-lib,把androidannotations-3.2.jar檔案拷貝進去。
2.選中項目,按右鍵,選擇Properties,在新視窗左邊可以看到Java Compiler,選中Java Compiler下的Annotation Processin,然後選中右邊的Enable project specific Settings,允許給項目一些特殊設定。
3.展開Annotation Processin,選中Factory Path,然後點擊右邊的Enable project specific Settings,最後點擊Add JARs,添加jar包。
4.選中我們剛剛建立檔案夾中的jar包,一路點擊OK即可,
好了,至此我們的開發環境上的配置就完成了
第三步
測試組態是否成功
在一個Activity上輸入@E,看看提示什麼:
如果你看到了@EActivity,那麼恭喜你,配置成功,如果沒有看到,請檢查以上步驟。
第四步
配置好了,接下來我們就要看看怎麼使用androidannotations了。
1.Activity註解的使用
修改資訊清單檔中的activity配置,我們要在MainActivity後面添加一個_:
<activity android:name=".MainActivity_" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
至於為什麼要把MainActivity改為MainActivity_,我在後面會給大家解釋。然後在MainActivity上添加註解:
@EActivity(R.layout.activity_main)public class MainActivity extends Activity {
刪除掉onCreate()方法中的setContentView(R.layout.activity_main);,
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }
為了方便起見,我們先在主布局檔案中添加一些控制項:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidannotations.MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button1" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button2" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button3" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button4" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Go TO Next Activity" /> <Button android:id="@+id/button6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="多線程事件" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /></LinearLayout>
這個時候我們運行看看,在沒有給Activity設定布局的情況下系統有沒有報錯:
沒有崩潰,所有內容正常顯示,由此可見@EActivity(R.layout.activity_main)代替了setContentView(R.layout.activity_main);,這個使用起來更加方便。
再介紹一個和Activity有關的註解,我們在Activity使用過程中,經常需要重新自訂標題列,從而需要隱藏系統預設的標題列,那麼這個該怎麼實現呢:
@WindowFeature({ Window.FEATURE_NO_TITLE , Window.FEATURE_INDETERMINATE_PROGRESS})@EActivity(R.layout.activity_main)public class MainActivity extends Activity {
:
標題列成功隱藏,比我們其他的隱藏標題的方式都方便吧。
2.執行個體化控制項註解
執行個體化控制項註解是androidannotations中又一個非常好用的註解,也解決了我們開發過程中最枯燥的一項工作,正常情況下,我們執行個體化一個控制項要使用findViewById,拿到控制項後再強轉為我們需要的類型,代碼量大,而且枯燥,那麼看看androidannotations帶給我們什麼驚喜呢?
我們的主布局檔案上一共有四個TextView,我使用以下三種方式來進行執行個體化:
@ViewById(R.id.textView1) TextView tv1; @ViewById TextView textView2; @ViewsById({R.id.textView3,R.id.textView4}) List<TextView> list;
第一種:@ViewById(R.id.textView1)這是非常標準的寫法。聲明一個控制項之後,然後使用@ViewById註解,在註解中說明這個控制項的id,這樣相當於代替了這樣一行代碼:
TextView tv1 = (TextView) this.findViewById(R.id.textView1);
第二種:我沒有指明這個註解標籤要用的id,那麼它是怎麼執行個體化的呢?在沒有指明的情況下,androidannotations會使用控制項名作為id,我的第二個控制項名叫做textView2,與xml中的布局id是一樣的,因此可以不用在註解中指定id.
第三種:如果要聲明多個控制項,可以把這些控制項放入一個List集合中,然後在註解中指明多個id即可。
控制項執行個體化之後,緊跟著就可以給控制項賦值了:
@AfterViews public void initTextView(){ tv1.setText("hello world!"); textView2.setText("hello android annotations!"); for(TextView tv:list){ tv.setText("hello lenve!"); } }
這個方法會在執行個體完控制項後執行。
3.事件註解
我們開發中用的較多的事件androidannotations幾乎都給我們提供了註解:
@TextChange @AfterTextChange @BeforeTextChange @EditorAction @FocusChange @CheckedChange @Touch @Click @LongClick @ItemClick @ItemLongClick @ItemSelect @OptionsItem @SeekBarProgressChange @SeekBarTouchStart @SeekBarTouchStop
我這裡挑個簡單的,也是最常用的說一下,算是拋磚引玉了:
@Click({R.id.button1,R.id.button2,R.id.button3}) public void btn_click(View v){ switch (v.getId()) { case R.id.button1: Toast.makeText(this,"btn1", Toast.LENGTH_LONG).show(); break; case R.id.button2: Toast.makeText(this,"btn2", Toast.LENGTH_LONG).show(); break; case R.id.button3: Toast.makeText(this,"btn3", Toast.LENGTH_LONG).show(); break; } } @Click(R.id.button4) public void btn4_click(){ Toast.makeText(this,"btn4", Toast.LENGTH_LONG).show(); }
在方法之上添加@Click註解,在註解中指明這是哪個控制項的點擊事件,如果是多個事件的點擊事件,就註明多個id,在方法中使用v.getId()方法來進行區分。如果只給一個控制項設定點擊事件,那看button4的例子。
事件的註解其實是比較簡單的,我就不多說了,大家有興趣可以查看官方文檔。
4.線程註解
這大概是最讓我激動的一個註解了。這裡主要給大家介紹兩個註解:
@Background@UiThread
毫無疑問,@Background是讓方法在子線程中運行,而@UiThreaad則是讓方法在UI線程中運行。
我們來實現一個簡單的效果,點擊一個按鈕之後,讓一個TextView自動更新值。
@Background public void doInBackground(){ try { for (int i = 0; i < 100; i++) { tvShowNumber(i); Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } } @UiThread public void tvShowNumber(int i) { list.get(1).setText(i+""); }
首先,在doInBackground方法中,每隔1秒執行一次tvShowNumber(i);方法,這個方法如果在主線程中運行會導致ANR異常,所以必須在子線程中運行,但是android中有不允許在子線程中更新UI線程,所以我們要在tvShowNumber方法上添加@UiThread標籤,表明該方法是在UI線程中啟動並執行。
看看:
這裡徹底拋棄了煩人的Message、Handler(此處該有掌聲)。
5.Activity之間傳值註解
Activity之間的跳轉經常需要資料的傳遞,在新的Activity中需要通過Bundle來獲得這些資料,還要判斷是否為空白,非常麻煩,看看androidannotations是怎麼解決這個問題的:
建立一個SecondActivity,注意要修改資訊清單檔,在檔案後面加上_:
<activity android:name=".SecondActivity_" android:label="@string/title_activity_second" > </activity>
SecondActivity接收MainActivity傳來的兩個參數,一個是name,一個是address,我們先來看看MainActivity中的代碼:
@Click(R.id.button5) public void go2NextActivity(){ //這裡要注意第二個Activity的寫法 Intent intent = new Intent(this,SecondActivity_.class); intent.putExtra("name", "張三"); intent.putExtra("address", "xi'an"); startActivity(intent); }
在SecondActivity中獲得MainActivity中傳來的值:
@Extra("name") String username; @Extra String address;
和上文一樣,如果參數名相同,則不用在註解中說明參數名稱,否則要指明。這樣就自動拿到MainActivity中傳來的值了。如果MainActivity中傳來的值為空白,也不會報錯,系統會自動處理異常情況。
6.資源檔註解
資源檔的使用我們也可以使用註解,比如,在strings.xml中添加一個字串:
<string name="welcome">hello China,Hello xi\'an and guangzhou</string>
在程式中我們要引用這個值:
@StringRes(R.string.welcome) String welcome;
這樣welcome就自動獲得了這裡的值。注意@StringRes匯入的包是import org.androidannotations.annotations.res.StringRes;,不是android內建的包,別上當了。
:
7關於加_的原因
最後再解決一個問題,就是什麼要在資訊清單檔中加_,要回答這個問題請大家先選中項目,按右鍵,取消apt_generated前面的一個點。
取消之後,我們的項目裡多了一個檔案夾:
這裡的檔案夾中的Activity就是我們剛才建立的Activity,只不過都多了一個底線,我們開啟這些Activity看看:
我們通過註解寫的布局檔案,它又在這裡給我們產生了,所以說,我們最終編譯時間用的是這裡的檔案,這也是為什麼資訊清單檔中要加底線了。
注意事項
最後強調一個注意事項,凡是使用註解的代碼,一定不要用private修飾最多可以用protected修飾,因為androidannotations在使用註解產生真正的源碼時,如果我們的東東被private修飾了,它就沒法調用這些東西了,所以最多隻能用protected修飾。
關於androidannotations的更多用法大家可以參考官方文檔
好了,關於Androidannotations的使用就給大家介紹到這裡,有什麼問題請留言。本項目源碼下載。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。若有錯誤地方,還望批評指正,不勝感激。