(一).前言:
前面咱們已經對於AndroidAnnotations注入框架的基本介紹項目配置和運行原理作了講解,今天咱們開始具體學習怎麼樣使用這個框架。
(二).@EActivity:
當Activity被使用AndroidAnnotations進行注入的時候,咱們須要使用@EActivity這個注入標籤。這個標籤的參數值必須是一個正確的layout ID(佈局ID),該做爲Activity的佈局(Content View)。固然你也能夠設置該參數值爲空,這表示不設置content view。可是在綁定完成以前咱們必須本身在onCreate()方法中設置佈局(content view)
使用方式以下:java
1 2android |
@EActivity(R.layout.dragger_inject_layout) Public class AnnotationsTestActivity extends BaseActivity{}web |
不使用佈局ID的方法以下:數據結構
1 2 3 4 5 6 7app |
@EActivity public class MainActvityextends BaseActivity{ @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }框架 |
(三).@Application:
3.1.基本使用
自AndroidAnnotations 2.2開始
你可使用@Application來對你的Android Application類進行註解ide
1 2函數 |
@EApplication public class FDApplication extendsApplication{}佈局 |
除了相關聯的views和extras以外,咱們可使用絕大多數AA註解。學習
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@EApplication public class MyApplication extends Application { public void onCreate() { super.onCreate(); initSomeStuff(); } @SystemService NotificationManager notificationManager; @Bean MyEnhancedDatastore datastore; @RestService MyService myService; @OrmLiteDao(helper = DatabaseHelper.class, model = User.class) UserDao userDao; @Background void initSomeStuff() { // init some stuff in background } } |
3.2.注入Application類
自AndroidAnnotations 2.1開始
你可使用@App來進行注入Application類
1 2 3 4 5 |
@EActivity public class MyActivity extends Activity { @App MyApplication application; } |
該一樣在任何類型注入組件中進行使用,例如:@EBBean
1 2 3 4 5 |
@EBean public class MyBean { @App MyApplication application; } |
(四).@EBean:
4.1.註解自定義類
咱們能夠對於非Android組件(例如:Activity,Service..)的類使用annotations,只須要使用@EBean來進行註解
1 2 3 |
@EBean public class MyClass { } |
【注】:使用@EBean註解的類必須只有一個構造函數,並且這個構造函數必須沒有參數。或者在AndroidAnnotations2.7版本上面,該構造函數能夠只有一個Context上下文引用類型的參數。
4.2.注入類
在另外一個註解類或者Android組件中使用這個註解類,咱們可使用@Bean;
1 2 3 4 5 |
@EBean public class MyOtherClass { @Bean MyClass myClass; } |
同時你能夠實現繼承依賴關係
1 2 3 4 5 |
@EActivity public class MyActivity extends Activity { @Bean MyOtherClass myOtherClass; } |
【注】當你在屬性聲明的地方使用@Bean注入,你總會獲得一個新的實例,除非那個類是一個單例。
值得咱們注意的是,註解生成的子類是final類型的,也就是說咱們不能在繼承生成的類。可是咱們能夠擴展原始的類。擴展出來的類一樣可使用註解。以下:
1 2 3 |
@EActivity public class MyChildActivity extends MyActivity { } |
4.3.注入實現類
若是你想在代碼中使用父類或者接口,那麼你能夠在@Bean注入的時候把實現類(implementation class)做爲注入的參數值。
1 2 3 4 5 6 7 8 |
@EActivity public class MyActivity extends Activity { /* A MyImplementation instance will be injected. * MyImplementation must be annotated with @EBean and implement MyInterface. */ @Bean(MyImplementation.class) MyInterface myInterface; } |
4.4.支持的Annotations
在被@Ebean註解的類中,咱們可使用絕大多數AA(Android平臺) 的Annotations;
1 2 3 4 5 6 7 8 |
@EBean public class MyClass { @SystemService NotificationManager notificationManager; @UiThread void updateUI() { } } |
4.5.支持的和View相關的Annotations
在被@EBean註解的類中 ,咱們可使用和View相關的Annotations(例如:@View,@Click…)
1 2 3 4 5 6 7 8 |
@EBean public class MyClass { @ViewById TextView myTextView; @Click(R.id.myButton) void handleButtonClick() { } } |
4.6.依賴注入以後回調執行相關代碼
當咱們@EBean註解的類的構造函數被執行的時候,它的屬性尚未被注入(初始化),若是在構建的時候,想在依賴注入以後執行相關代碼,你能夠在一些方法上面使用@AfterInject Annotation,以下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@EBean public class MyClass { @SystemService NotificationManager notificationManager; @Bean MyOtherClass dependency; public MyClass() { // notificationManager and dependency are null } @AfterInject public void doSomethingAfterInjection() { // notificationManager and dependency are set } } |
4.7.做用域
AndroidAnnotations如今提供兩種做用域實例
①:默認的做用域:每次建立都會建立一個新的實例對象
②:單一做用域:第一次建立使用的時候會生成一個新實例,而後該實例會保持,其餘都會使用一樣的實例。
1 2 3 |
@EBean(scope = Scope.Singleton) public class MySingleton { } |
(五).@EFragment:
5.1.支持FragmentActivity註解
從AndroidAnnotations2.1版本開始
在AndroidAnnotations2.6版本以前,這是不支持Fragment註解,可是可使用FragmentActivity來代替Activity.
1 2 3 |
@EActivity(R.id.main) public class DetailsActivity extends FragmentActivity { } |
5.2.Fragment支持
從AndroidAnnotations2.6版本開始
AndroidAnnotations同時支持android.app.Fragment和android.support.v4.app.Fragment.而且它能夠根據Fragment類型選擇使用正確的APIs
5.3.Fragment註解
咱們可使用@EFragment來對Fragment進行註解.
1 2 3 |
@EFragment public class MyFragment extends Fragment { } |
AndroidAnnotations將會生成帶有一個下劃線的子類,例如:MyFragment_。當咱們建立一個新的fragmetns實例的時候,你應該在xml 佈局文件中使用生成的子類,以下:
1 2 3 4 5 6 7 8 9 10 11 |
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <fragment android:id="@+id/myFragment" android:name="com.company.MyFragment_" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </linearlayout> |
建立以下:
1 |
MyFragment fragment=new MyFragment_(); |
或者你可使用構建器
1 |
MyFragment fragmeng=MyFragment_.builder().build(); |
你同時能夠在Fragment中使用各類其餘類型的註解(annotations)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
@EFragment public class MyFragment extends Fragment { @Bean SomeBean someBean; @ViewById TextView myTextView; @App MyApplication customApplication; @SystemService ActivityManager activityManager; @OrmLiteDao(helper = DatabaseHelper.class, model = User.class) UserDao userDao; @Click void myButton() { } @UiThread void uiThread() { } @AfterInject void calledAfterInjection() { } @AfterViews void calledAfterViewInjection() { } @Receiver(actions = "org.androidannotations.ACTION_1") protected void onAction1() { } } |
5.4.Fragment佈局
Fragment獲取view的標準的方法是重寫onCreateView()方法
1 2 3 4 5 6 7 |
@EFragment public class MyFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.my_fragment_layout, container, false); return view; } } |
你能夠設置@EFragment的參數值,來讓AndroidAnnotations來進行處理佈局
1 2 3 |
@EFragment(R.layout.my_fragment_layout) public class MyFragment extends Fragment { } |
若是你須要重寫onCreateView()方法,例如由於你須要訪問savedInstanceState,此時你仍然可讓AndroidAnnotations來處理佈局建立,而且return null
1 2 3 4 5 6 |
@EFragment(R.layout.my_fragment_layout) public class MyFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return null; } } |
5.5.注入Fragments
咱們能夠在類中使用@EActivity,@EFragment,@Eview,@EViewGroup,@EBean,使用@FragmentById或者@FragmentByTag來進行注入fragments。
【注】推薦使用哪一個@FragmentById而不是@FragmentByTag,由於後者沒有編譯時候的驗證。
請注意@FragmentById和@FragmentByTag僅僅能注入fragments而不是建立它們。因此它們只能存在於Activity中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@EActivity(R.layout.fragments) public class MyFragmentActivity extends FragmentActivity { @FragmentById MyFragment myFragment; @FragmentById(R.id.myFragment) MyFragment myFragment2; @FragmentByTag MyFragment myFragmentTag; @FragmentByTag("myFragmentTag") MyFragment myFragmentTag2; } |
5.6.DialogFragments
很是惋惜的是,若是你使用@EFragment進行注入,你沒法經過onCreteDialog()方法來建立一個Dialog新的實例。你應該調用super.onCreateDialog(),該該會返回一個Dialog實例。而後你能夠一個@AfterViews注入的方法中設置views。
(六).@EProvider
自AndroidAnnotations2.4開始
你可使用@EProvider來對Android內容提供者進行註解。
1 2 3 |
@EProvider public class MyContentProvider extends ContentProvider { } |
除了相關views和extras註解標籤之外,咱們還可使用絕大多數註解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@EProvider public class MyContentProvider extends ContentProvider { @SystemService NotificationManager notificationManager; @Bean MyEnhancedDatastore datastore; @OrmLiteDao(helper = DatabaseHelper.class, model = User.class) UserDao userDao; @UiThread void showToast() { Toast.makeText(getContext().getApplicationContext(), "Hello World!", Toast.LENGTH_LONG).show(); } // ... } |
(七).@EReceiver
7.1.註解廣播接收者
自AndroidAnnotations2.4開始
咱們可使用@EReceiver來對Android廣播接受者進行註解
1 2 3 |
@EReceiver public class MyReceiver extends BroadcastReceiver { } |
除了相關views和extras之外,還可使用絕大多數AA註解
1 2 3 4 5 6 7 8 9 10 |
@EReceiver public class MyReceiver extends BroadcastReceiver { @SystemService NotificationManager notificationManager; @Bean SomeObject someObject; } |
7.2.註解廣播(Action)
自AndroidAnnotations3.2開始
使用@ReceiverAction能夠在一個被註解的廣播接受者中簡單處理廣播
通常狀況下默認方法onReceive()來進行處理廣播,可是咱們能夠經過@RecevierAction加入參數值來傳遞另一個廣播。
使用@ReceiverAction註解的方法可能存在如下這種參數類型:
- 在onReceiver(Contenxt context,Intent intent)中的context上下文引用
- 在onReceiver(Context context,Intent intent)中的intent
- 若是咱們設置@ReceiverAction.Extra的值, 任何被@ReceiverAction.Extra註解的本地android.os.Parcelable或者java.io.Serializable類型的參數。這些參數將會加入到intent得extra中。加入intent.extra中的key的爲@ReceiverAction.Extra中參數值。
看以下例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@EReceiver public class MyIntentService extends BroadcastReceiver { @ReceiverAction("BROADCAST_ACTION_NAME") void mySimpleAction(Intent intent) { // ... } @ReceiverAction void myAction(@ReceiverAction.Extra String valueString, Context context) { // ... } @ReceiverAction void anotherAction(@ReceiverAction.Extra("specialExtraName") String valueString, @ReceiverAction.Extra long valueLong) { // ... } @Override public void onReceive(Context context, Intent intent) { // empty, will be overridden in generated subclass } } |
【注】由於BroadcastReceiver的onRecevier是一個抽象方法,因此你不得不添加一個空方法的實現。爲了方便起見,AndroidAnnotations框架已經提供AbstractBroadcastReceiver ,該類已經實現了onReceiver()方法,因此你在使用的時候,能夠不實現該方法。
【注】如今咱們能夠在@ReceiverAction參數中加入多個廣播並進行處理,以下:
1 2 3 4 |
@ReceiverAction({"MULTI_BROADCAST_ACTION1", "MULTI_BROADCAST_ACTION2"}) void multiAction(Intent intent) { // ... } |
7.3.數據結構(Data Schemes)
咱們可使用dataSchemes參數來設置一個或者多個數據來讓Receiver進行處理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@EReceiver public class MyIntentService extends BroadcastReceiver { @ReceiverAction(actions = android.content.Intent.VIEW, dataSchemes = "http") protected void onHttp() { // Will be called when an App wants to open a http website but not for https. } @ReceiverAction(actions = android.content.Intent.VIEW, dataSchemes = {"http", "https"}) protected void onHttps() { // Will be called when an App wants to open a http or https website. } } |
7.4.@Receiver註解說明
在Activity.Fragment,Service,咱們可使用@Receiver註解,而不是直接聲明一個BroadcastReceiver
1 2 3 4 5 6 |
@EActivity public class MyActivity extends Activity { @Receiver(actions = "org.androidannotations.ACTION_1") protected void onAction1() { } } |
(八).@EIntentService
自AndroidAnnotations3.0開始
咱們可使用@EIntentService註解的Android IntentService來處理@ServiceAction註解的方法中的Actions。對於此註解咱們一樣可使用除views和extras之外的不少AA註解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@EIntentService public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @ServiceAction void mySimpleAction() { // ... } @ServiceAction void myAction(String param) { // ... } @Override protected void onHandleIntent(Intent intent) { // Do nothing here } } |
咱們可使用內部構建器來啓動IntentService
1 2 3 |
MyIntentService_.intent(getApplication()) .myAction("test") .start(); |
若是在構建器重調用了多個Actions,那麼只有最後一個action會被執行。
自AndroidAnnotations3.3開始
【注】由於IntentService的onHandleIntent是一個抽象方法,因此你這邊不得不添加一個空方法實現。爲了方便起見這邊提供了AbstractIntentService,該類實現了抽象方法。當你使用該類的時候,若是不須要你能夠不用實現onHandleIntent。
(九).@EService
自AndroidAnnotations2.4起
你可使用@EService來進行註冊Android Service
1 2 3 |
@EService public class MyService extends Service { } |
除了相關的views和extras以外,一樣可使用絕大多數AA註解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
@EService public class MyService extends IntentService { @SystemService NotificationManager notificationManager; @Bean MyEnhancedDatastore datastore; @RestService MyRestClient myRestClient; @OrmLiteDao(helper = DatabaseHelper.class, model = User.class) UserDao userDao; public MyService() { super(MyService.class.getSimpleName()); } @Override protected void onHandleIntent(Intent intent) { // Do some stuff... showToast(); } @UiThread void showToast() { Toast.makeText(getApplicationContext(), "Hello World!", Toast.LENGTH_LONG).show(); } } |
咱們能夠經過內部構建器來進行打開這個Service
1 |
MyService_.intent(getApplication()).start(); |
自AndroidAnnotations3.0起
同時內部構建器也提供stop()方法來進行中止該Service
1 |
MyService_.intent(getApplication()).stop(); |
(十).@EView
10.1.注入自定義views
若是你想要建立自定義組件,咱們可使用@EView和@EViewGroup來進行註解
10.2.爲何要使用自定義組件?
在咱們的APP中不少地方咱們可能會複製一樣的佈局代碼,而且我複製和調用相同的代碼來控制這些佈局。基於前面這些緣由
,咱們可使用自定義組件來解決這些問題,讓咱們的工做變得更加輕鬆。
10.3.使用@EView來註解自定義views
自AndroidAnnotations2.4起
咱們只須要建立一個繼承與View的新類,而後在這個View中就可使用annotations了。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@EView public class CustomButton extends Button { @App MyApplication application; @StringRes String someStringResource; public CustomButton(Context context, AttributeSet attrs) { super(context, attrs); } } |
如今你就能夠在佈局文件中使用這個View了(【注】不要忘記"_")
1 2 3 4 5 6 7 8 9 10 11 12 13 |
< ?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com .androidannotations.view.CustomButton_ android:layout_width="match_parent" android:layout_height="wrap_content" /> <!-- ... --> </linearlayout> |
你也可使用程序化建立方式
1 |
CustomButton button = CustomButton_.build(context); |
10.4.使用@EViewGroup來註解自定義ViewGroups
自AndroidAnnotations2.2起
①.How to create it?
首先咱們須要爲這個組件建立一個佈局文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
< ?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" > <imageview android:id="@+id/image" android:layout_alignParentRight="true" android:layout_alignBottom="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/check" /> <textview android:id="@+id/title" android:layout_toLeftOf="@+id/image" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="12pt" /> <textview android:id="@+id/subtitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/title" android:textColor="#FFdedede" android:textSize="10pt" /> </merge> |
【注】你有沒有發現上面的merge標籤?當這個佈局被進行加載的時候,子節點會被直接加入到父節點中,這樣就能夠減小布局層級關係。
正如你看到是這般使用了不少RelativeLayout特殊佈局屬性(layout_alignParentRight,layout_alignBottom,layout_toLeftOf,etc..),這是由於我知道這個佈局會被加載到RelativeLayout中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@EViewGroup(R.layout.title_with_subtitle) public class TitleWithSubtitle extends RelativeLayout { @ViewById protected TextView title, subtitle; public TitleWithSubtitle(Context context, AttributeSet attrs) { super(context, attrs); } public void setTexts(String titleText, String subTitleText) { title.setText(titleText); subtitle.setText(subTitleText); } } |
就這樣使用便可,是否是很簡單呢?
如今讓咱們來看一下該怎麼樣使用這個自定義組件
②.How to use it?
自定義組件和其餘View控件同樣,在佈局文件中進行聲明(【注】不要忘記控件名稱最後的"_")
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
< ?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <com .androidannotations.viewgroup.TitleWithSubtitle_ android:id="@+id/firstTitle" android:layout_width="match_parent" android:layout_height="wrap_content" /> <com .androidannotations.viewgroup.TitleWithSubtitle_ android:id="@+id/secondTitle" android:layout_width="match_parent" android:layout_height="wrap_content" /> <com .androidannotations.viewgroup.TitleWithSubtitle_ android:id="@+id/thirdTitle" android:layout_width="match_parent" android:layout_height="wrap_content" /> </linearlayout> |
由於咱們使用AA框架,因此咱們會很是容易在Activity中獲得這些注入的自定義組件而且去使用它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
@EActivity(R.layout.main) public class Main extends Activity { @ViewById protected TitleWithSubtitle firstTitle, secondTitle, thirdTitle; @AfterViews protected void init() { firstTitle.setTexts("decouple your code", "Hide the component logic from the code using it."); secondTitle.setTexts("write once, reuse anywhere", "Declare you component in multiple " + "places, just as easily as you " + "would put a single basic View."); thirdTitle.setTexts("Let's get stated!", "Let's see how AndroidAnnotations can make it easier!"); } } |