## (一).前言:
前面我們已經對于AndroidAnnotations注入框架的基本介紹項目配置和運行原理做了講解,今天我們開始具體學習怎么樣使用這個框架。
FastDev4Android框架項目地址:[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)?
本博客已完成下面相關注解方式更新:

## (二).@EActivity:
當Activity被使用AndroidAnnotations進行注入的時候,我們需要使用@EActivity這個注入標簽。這個標簽的參數值必須是一個正確的layout ID(布局ID),該作為Activity的布局(Content View)。當然你也可以設置該參數值為空,這表示不設置content view。但是在綁定完成之前我們必須自己在onCreate()方法中設置布局(content view)
使用方式如下:
~~~
@EActivity(R.layout.dragger_inject_layout)
Public classAnnotationsTestActivity extends BaseActivity{}
~~~
不使用布局ID的方法如下:
~~~
@EActivity
Public classMainActvityextends BaseActivity{
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
~~~
## (三).@Application:
3.1.基本使用
自AndroidAnnotations 2.2開始
你可以使用@Application來對你的AndroidApplication類進行注解
~~~
@EApplication
publicclassFDApplicationextendsApplication{}
~~~
除了相關聯的views和extras之外,我們可以使用絕大多數AA注解。
~~~
@EApplication
public classMyApplication 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類
~~~
@EActivity
public classMyActivity extends Activity {
@App
MyApplication application;
}
~~~
該同樣在任何類型注入組件中進行使用,例如:@EBBean
~~~
@EBean
public class MyBean{
@App
MyApplication application;
}
~~~
## (四).@EBean:
4.1.注解自定義類
我們可以對于非Android組件(例如:Activity,Service..)的類使用annotations,只需要使用@EBean來進行注解
~~~
@EBean
public class MyClass{
}
~~~
【注】:使用@EBean注解的類必須只有一個構造函數,而且這個構造函數必須沒有參數。或者在AndroidAnnotations2.7版本上面,該構造函數可以只有一個Context上下文引用類型的參數。
4.2.注入類
在另一個注解類或者Android組件中使用這個注解類,我們可以使用@Bean;
~~~
@EBean
public classMyOtherClass {
@Bean
MyClass myClass;
}
~~~
同時你可以實現繼承依賴關系
~~~
@EActivity
public classMyActivity extends Activity {
@Bean
MyOtherClass myOtherClass;
}
~~~
【注】當你在屬性聲明的地方使用@Bean注入,你總會得到一個新的實例,除非那個類是一個單例。
值得我們注意的是,注解生成的子類是final類型的,也就是說我們不能在繼承生成的類。但是我們可以擴展原始的類。擴展出來的類同樣可以使用注解。如下:
~~~
@EActivity
public classMyChildActivity extends MyActivity {
}
~~~
4.3.注入實現類
如果你想在代碼中使用父類或者接口,那么你可以在@Bean注入的時候把實現類(implementation class)作為注入的參數值。
~~~
@EActivity
public classMyActivity extends Activity {
/* A MyImplementation instance will beinjected.
* MyImplementation must be annotated with@EBean and implement MyInterface.
*/
@Bean(MyImplementation.class)
MyInterface myInterface;
}
~~~
4.4.支持的Annotations
在被@Ebean注解的類中,我們可以使用絕大多數AA(Android平臺)的Annotations;
~~~
@EBean
public class MyClass{
@SystemService
NotificationManager notificationManager;
@UiThread
void updateUI() {
}
}
~~~
4.5.支持的和View相關的Annotations
在被@EBean注解的類中,我們可以使用和View相關的Annotations(例如:@View,@Click…)
~~~
@EBean
public class MyClass{
@ViewById
TextView myTextView;
@Click(R.id.myButton)
void handleButtonClick() {
}
}
~~~
4.6.依賴注入之后回調執行相關代碼
當我們@EBean注解的類的構造函數被執行的時候,它的屬性還沒有被注入(初始化),如果在構建的時候,想在依賴注入之后執行相關代碼,你可以在一些方法上面使用@AfterInject Annotation,如下所示
~~~
@EBean
public class MyClass{
@SystemService
NotificationManager notificationManager;
@Bean
MyOtherClass dependency;
public MyClass() {
// notificationManager and dependency arenull
}
@AfterInject
public void doSomethingAfterInjection() {
// notificationManager and dependency areset
}
}
~~~
4.7.作用域
AndroidAnnotations現在提供兩種作用域實例
①:默認的作用域:每次創建都會創建一個新的實例對象
②:單一作用域:第一次創建使用的時候會生成一個新實例,然后該實例會保持,其他都會使用同樣的實例。
~~~
@EBean(scope =Scope.Singleton)
public classMySingleton {
}
~~~
## (五).@EFragment:
5.1.支持FragmentActivity注解
從AndroidAnnotations2.1版本開始
在AndroidAnnotations2.6版本之前,這是不支持Fragment注解,但是可以使用FragmentActivity來代替Activity.
~~~
@EActivity(R.id.main)
public classDetailsActivity extends FragmentActivity {
}
~~~
5.2.Fragment支持
從AndroidAnnotations2.6版本開始
AndroidAnnotations同時支持android.app.Fragment和android.support.v4.app.Fragment.并且它可以根據Fragment類型選擇使用正確的APIs
5.3.Fragment注解
我們可以使用@EFragment來對Fragment進行注解.
~~~
@EFragment
public classMyFragment extends Fragment {
}
~~~
AndroidAnnotations將會生成帶有一個下劃線的子類,例如:MyFragment_。當我們創建一個新的fragmetns實例的時候,你應該在xml布局文件中使用生成的子類,如下:
~~~
<LinearLayoutxmlns: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>
~~~
創建如下:
MyFragmentfragment=new MyFragment_();
或者你可以使用構建器
MyFragmentfragmeng=MyFragment_.builder().build();
你同時可以在Fragment中使用各種其他類型的注解(annotations)
~~~
@EFragment
public classMyFragment 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()方法
~~~
@EFragment
public classMyFragment extends Fragment {
public View onCreateView(LayoutInflaterinflater, ViewGroup container, Bundle savedInstanceState) {
View view =inflater.inflate(R.layout.my_fragment_layout, container, false);
return view;
}
}
~~~
你可以設置@EFragment的參數值,來讓AndroidAnnotations來進行處理布局
~~~
@EFragment(R.layout.my_fragment_layout)
public classMyFragment extends Fragment {
}
~~~
如果你需要重寫onCreateView()方法,例如因為你需要訪問savedInstanceState,此時你仍然可以讓AndroidAnnotations來處理布局創建,并且return?null
~~~
@EFragment(R.layout.my_fragment_layout)
public classMyFragment extends Fragment {
public View onCreateView(LayoutInflaterinflater, ViewGroup container, Bundle savedInstanceState) {
return null;
}
}
~~~
5.5.注入Fragments
我們可以在類中使用@EActivity,@EFragment,@Eview,@EViewGroup,@EBean,使用@FragmentById或者@FragmentByTag來進行注入fragments。
【注】推薦使用哪個@FragmentById而不是@FragmentByTag,因為后者沒有編譯時候的驗證。
請注意@FragmentById和@FragmentByTag僅僅能注入fragments而不是創建它們。所以它們只能存在于Activity中
~~~
@EActivity(R.layout.fragments)
public classMyFragmentActivity 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內容提供者進行注解。
~~~
@EProvider
public classMyContentProvider extends ContentProvider {
}
~~~
除了相關views和extras注解標簽以外,我們還可以使用絕大多數注解。
~~~
@EProvider
public classMyContentProvider extends ContentProvider {
@SystemService
NotificationManager notificationManager;
@Bean
MyEnhancedDatastore datastore;
@OrmLiteDao(helper = DatabaseHelper.class,model = User.class)
UserDao userDao;
@UiThread
void showToast() {
Toast.makeText(getContext().getApplicationContext(), "HelloWorld!", Toast.LENGTH_LONG).show();
}
// ...
}
~~~
## (七).@EReceiver
7.1.注解廣播接收者
自AndroidAnnotations2.4開始
我們可以使用@EReceiver來對Android廣播接受者進行注解
~~~
@EReceiver
public classMyReceiver extends BroadcastReceiver {
}
~~~
除了相關views和extras以外,還可以使用絕大多數AA注解
~~~
@EReceiver
public classMyReceiver extends BroadcastReceiver {
@SystemService
NotificationManager notificationManager;
@Bean
SomeObject someObject;
}
~~~
7.2.注解廣播(Action)
自AndroidAnnotations3.2開始
使用@ReceiverAction可以在一個被注解的廣播接受者中簡單處理廣播
一般情況下默認方法onReceive()來進行處理廣播,但是我們可以通過@RecevierAction加入參數值來傳遞另外一個廣播。
使用@ReceiverAction注解的方法可能存在以下這種參數類型:
1. 在onReceiver(Contenxt context,Intent intent)中的context上下文引用
2. 在onReceiver(Context context,Intent intent)中的intent
3. 如果我們設置@ReceiverAction.Extra的值,任何被@ReceiverAction.Extra注解的本地android.os.Parcelable或者java.io.Serializable類型的參數。這些參數將會加入到intent得extra中。加入intent.extra中的key的為@ReceiverAction.Extra中參數值。
看如下例子:
~~~
@EReceiver
public classMyIntentService extends BroadcastReceiver {
@ReceiverAction("BROADCAST_ACTION_NAME")
void mySimpleAction(Intent intent) {
// ...
}
@ReceiverAction
void myAction(@ReceiverAction.Extra StringvalueString, Context context) {
// ...
}
@ReceiverAction
voidanotherAction(@ReceiverAction.Extra("specialExtraName") StringvalueString, @ReceiverAction.Extra long valueLong) {
// ...
}
@Override
public void onReceive(Context context,Intent intent) {
// empty, will be overridden ingenerated subclass
}
}
~~~
【注】因為BroadcastReceiver的onRecevier是一個抽象方法,所以你不得不添加一個空方法的實現。為了方便起見,AndroidAnnotations框架已經提供AbstractBroadcastReceiver,該類已經實現了onReceiver()方法,所以你在使用的時候,可以不實現該方法。
【注】現在我們可以在@ReceiverAction參數中加入多個廣播并進行處理,如下:
~~~
@ReceiverAction({"MULTI_BROADCAST_ACTION1","MULTI_BROADCAST_ACTION2"})
void multiAction(Intent intent) {
// ...
}
~~~
7.3.數據結構(Data Schemes)
我們可以使用dataSchemes參數來設置一個或者多個數據來讓Receiver進行處理
~~~
@EReceiver
public classMyIntentService extends BroadcastReceiver {
@ReceiverAction(actions =android.content.Intent.VIEW, dataSchemes = "http")
protected void onHttp() {
// Will be called when an App wants to opena 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 opena http or https website.
}
}
~~~
7.4.@Receiver注解說明
在Activity.Fragment,Service,我們可以使用@Receiver注解,而不是直接聲明一個BroadcastReceiver
~~~
@EActivity
public classMyActivity extends Activity {
@Receiver(actions ="org.androidannotations.ACTION_1")
protected void onAction1() {
}
}
~~~
## (八).@EIntentService
自AndroidAnnotations3.0開始
我們可以使用@EIntentService注解的Android IntentService來處理@ServiceAction注解的方法中的Actions。對于此注解我們同樣可以使用除views和extras以外的很多AA注解
~~~
@EIntentService
public classMyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
@ServiceAction
void mySimpleAction() {
// ...
}
@ServiceAction
void myAction(String param) {
// ...
}
@Override
protected void onHandleIntent(Intentintent) {
// Do nothing here
}
}
~~~
我們可以使用內部構建器來啟動IntentService
~~~
MyIntentService_.intent(getApplication())//
.myAction("test") //
.start();
~~~
如果在構建器重調用了多個Actions,那么只有最后一個action會被執行。
自AndroidAnnotations3.3開始
【注】因為IntentService的onHandleIntent是一個抽象方法,所以你這邊不得不添加一個空方法實現。為了方便起見這邊提供了AbstractIntentService,該類實現了抽象方法。當你使用該類的時候,如果不需要你可以不用實現onHandleIntent。
# (九).@EService
自AndroidAnnotations2.4起
你可以使用@EService來進行注冊Android?Service
~~~
@EService
public classMyService extends Service {
}
~~~
除了相關的views和extras之外,同樣可以使用絕大多數AA注解
~~~
@EService
public classMyService 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
~~~
MyService_.intent(getApplication()).start();
~~~
自AndroidAnnotations3.0起
同時內部構建器也提供stop()方法來進行停止該Service
MyService_.intent(getApplication()).stop();
## (十).@EView
10.1.注入自定義views
如果你想要創建自定義組件,我們可以使用@EView和@EViewGroup來進行注解
10.2.為什么要使用自定義組件?
在我們的APP中很多地方我們可能會復制同樣的布局代碼,并且我復制和調用相同的代碼來控制這些布局。基于前面這些原因
,我們可以使用自定義組件來解決這些問題,讓我們的工作變得更加輕松。
10.3.使用@EView來注解自定義views
自AndroidAnnotations2.4起
我們只需要創建一個繼承與View的新類,然后在這個View中就可以使用annotations了。
~~~
@EView
public classCustomButton extends Button {
@App
MyApplication application;
@StringRes
String someStringResource;
public CustomButton(Context context,AttributeSet attrs) {
super(context, attrs);
}
}
~~~
現在你就可以在布局文件中使用這個View了(【注】不要忘記"_")
~~~
<?xmlversion="1.0" encoding="utf-8"?>
<LinearLayoutxmlns: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>
~~~
你也可以使用程序化創建方式
~~~
CustomButton button= CustomButton_.build(context);
~~~
10.4.使用@EViewGroup來注解自定義ViewGroups
自AndroidAnnotations2.2起
①.How to create it?
首先我們需要為這個組件創建一個布局文件
~~~
<?xmlversion="1.0" encoding="utf-8"?>
<mergexmlns: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中。
~~~
@EViewGroup(R.layout.title_with_subtitle)
public classTitleWithSubtitle 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控件一樣,在布局文件中進行聲明(【注】不要忘記控件名稱最后的"_")
~~~
<pre name="code" class="html"><?xmlversion="1.0" encoding="utf-8"?>
<LinearLayoutxmlns: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中得到這些注入的自定義組件并且去使用它。
~~~
@EActivity(R.layout.main)
public class Mainextends Activity {
@ViewById
protected TitleWithSubtitle firstTitle,secondTitle, thirdTitle;
@AfterViews
protected void init() {
firstTitle.setTexts("decouple yourcode",
"Hide the component logicfrom the code using it.");
secondTitle.setTexts("write once,reuse anywhere",
"Declare you component inmultiple " +
"places, just as easily asyou " +
"would put a single basicView.");
thirdTitle.setTexts("Let's getstated!",
"Let's see howAndroidAnnotations can make it easier!");
}
}
~~~
在@EViewGroup注解的類中也同時支持絕大多數AndroidAnnotations注解方式,趕快去嘗試使用吧。
到此位置關于AndroidAnnotations注解組件的方式和使用方法已經全部講解完成了。
FastDev4Android項目已經添加配置了AndroidAnnotations框架,后期的框架項目中也會主要使用這個DI框架,.歡迎大家去Github站點進行clone或者下載瀏覽.
[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)?
同時歡迎大家star和fork整個開源快速開發框架項目~如果有什么意見和反饋,歡迎留言,必定第一時間回復。也歡迎有同樣興趣的童鞋加入到該項目中來,一起維護該項目。
- 前言
- Android快速開發框架介紹(一)
- Android首頁圖片自動無限循環輪播Gallery+FlowIndicator(二)
- Android 列表下拉刷新組件PullToRefreshListView使用(三)
- Android 數據緩存器ACache的詳解和使用(四)
- Android崩潰異常捕捉CustomCrash,提升用戶體驗(五)
- Android實現沉浸式狀態欄(六)
- AndroidAnnnotations注入框架介紹和Android Studios基本配置(七)
- AndroidAnnnotations注入框架的工作原理(八)
- AndroidAnnnotations注入框架使用之注入組件Components(九)
- AndroidAnnnotations注入框架使用之Injection標簽詳解(十)
- AndroidAnnnotations注入框架使用之事件綁定Event Binding(十一)
- AndroidAnnnotations注入框架使用之線程處理Threading(十二)
- AndroidAnnnotations注入框架使用之第三方框架集成RoboGuice(十三)
- AndroidAnnnotations注入框架使用之第三方框架集成Otto事件總線(十四)
- AndroidAnnnotations注入框架使用之第三方框架集成OrmLite(十五)
- AndroidAnnnotations注入框架使用之最佳實踐之Adapters和lists(十六)
- AndroidAnnnotations注入框架使用之最佳實踐SharedPreferences(十七)
- Android MVP開發模式詳解(十九)
- 消息總線EventBus的基本使用(二十)
- 消息總線EventBus源碼分析以及與Otto框架對比(二十一)
- 列表頭生成帶文本或者字母的圖片開源庫TextDrawable使用和詳解(二十二)
- 重寫WebView網頁加載以及JavaScript注入詳解(二十三)
- BaseAdapterHelper的基本使用介紹,讓你擺脫狂寫一堆Adapter煩惱(二十四)
- BaseAdapterHelper詳解源碼分析,讓你擺脫狂寫一堆Adapter煩惱(二十五)
- Volley完全解析之基礎使用(二十六)
- Volley完全解析之進階最佳實踐與二次封裝(二十七)
- RecyclerView完全解析,讓你從此愛上它(二十八)
- RecyclerView完全解析之打造新版類Gallery效果(二十九)
- RecyclerView完全解析之結合AA(Android Annotations)注入框架實例(三十)
- RecyclerView完全解析之下拉刷新與上拉加載SwipeRefreshLayout(三十一)
- CardView完全解析與RecyclerView結合使用(三十二)
- 神器ViewDragHelper完全解析,媽媽再也不擔心我自定義ViewGroup滑動View操作啦~(三十三)
- 神器ViewDragHelper完全解析之詳解實現QQ5.X側滑酷炫效果(三十四)
- 實例解析之SwipeRefreshLayout+RecyclerView+CardView(三十五)
- HorizontalScrollView,Fragment,FragmentStatePagerAdapter打造網易新聞Tab及滑動頁面效果(三十六)
- Android Design支持庫TabLayout打造仿網易新聞Tab標簽效果(三十七)
- 打造QQ6.X最新版本側滑界面效果(三十八)