(一).前言:
前面我們已經對於AndroidAnnotations框架的註入組件的方式做瞭講解,今天我們開始具體學習一下Injection標簽使用。
本博客已完成Injection更新如下:
(二).@AfterExtras
自AndroidAnnotations3.1起
如果你需要在extras註入之後執行相關代碼,你可以在該要執行的方法上面使用@AfterExtras註解
@EActivity public class MyClass{ @Extra String someExtra; @Extra int anotherExtra; @AfterExtras public void doSomethingAfterExtrasInjection(){ // someExtra and anotherExtra are set tothe value contained in the incoming intent // if an intent does not contain one of theextra values the field remains unchanged } }
(三).@AfterInject
如下的例子:當然我們的被@EBean註解類的構造函數被調用,它的屬性還沒有被註入,如果你需要在編譯的時候,依賴註入的之後執行相關的代碼。你可以在需要執行的方法使用@AfterInject註入。
@EBean public class MyClass{ @SystemService NotificationManager notificationManager; @Bean MyOtherClass dependency; public MyClass() { // notificationManager and dependency arenull } @AfterInject public void doSomethingAfterInjection() { // notificationManager and dependency areset } }
(四).@AfterViews
使用@AfterViews註解過後的方法會在views進行綁定之後被調用。
[註]當onCreate()方法被調用的時候,然後@ViewById註入的屬性還沒有被執行。因此你可以在依賴註入的Views中使用@AfterViews。
實例如下:
@EActivity(R.layout.main) public classMyActivity extends Activity { @ViewById TextView myTextView; @AfterViews void updateTextWithDate() { myTextView.setText(Date: +new Date()); } [...]
同樣你可以使用@AfterViews註解多個方法。但是要記住,在onCreate()方法不要使用任務View相關的屬性。
@EActivity(R.layout.main) public classMyActivity extends Activity { @ViewById TextView myTextView; @Override public void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); // DON'T DO THIS !! It will throw aNullPointerException, myTextView is not set yet. // myTextView.setText(Date: + new Date()); } [...]
(五).@App
自AndroidAnnotations 2.1開始
你可以使用@App來進行註入Application類
@EActivity public classMyActivity extends Activity { @App MyApplication application; }
該同樣在任何類型註入組件中進行使用,例如:@EBBean
@EBean public class MyBean{ @App MyApplication application; }
(六).@Bean
在另一個註解類或者Android組件中使用這個註解類,我們可以使用@Bean;
@EBean public classMyOtherClass { @Bean MyClass myClass; }
同時你可以實現繼承依賴關系
@EActivity public classMyActivity extends Activity { @Bean MyOtherClass myOtherClass; }
【註】當你在屬性聲明的地方使用@Bean註入,你總會得到一個新的實例,除非那個類是一個單例。
值得我們註意的是,註解生成的子類是final類型的,也就是說我們不能在繼承生成的類。但是我們可以擴展原始的類。擴展出來的類同樣可以使用註解。如下:
@EActivity public classMyChildActivity extends MyActivity { }
(七).@Extra
自AndroidAnnotations1.0起
@Extra註解表示Activity中的屬性應該註解成Intent中相應的Extra數據,由此用來打開Activity
使用實例如下:
@EActivity public classMyActivity extends Activity { @Extra(myStringExtra) String myMessage; @Extra(myDateExtra) Date myDateExtraWithDefaultValue = newDate(); }
自AndroidAnnotations2.6起
如果@Extra註解中沒有提供任何值,那麼將會直接使用屬性的名字。
@EActivity public classMyActivity extends Activity { // The name of the extra will bemyMessage @Extra String myMessage; }
你可以通過Intent構建起來傳遞額外的數據值
MyActivity_.intent().myMessage(hello).start();
(八).@FragmentArg
使用@FragmentArg註解Fragment中的屬性相當於Fragment Argument
生成的構建器的set方法總會使用argument相同的名字。默認情況下綁定值的key的名字就是該註入的屬性的名字,但是你可以給以個@FragmentArg的參數值來改變它。
實例:
@EFragment public classMyFragment extends Fragment { @FragmentArg(myStringArgument) String myMessage; @FragmentArg String anotherStringArgument; @FragmentArg(myDateExtra) Date myDateArgumentWithDefaultValue = newDate(); }
使用Fragment構建器來進行使用。
MyFragmentmyFragment = MyFragment_.builder() .myMessage(Hello) .anotherStringArgument(World) .build();
(九).@FragmentById和@FragmentByTag
我們可以在類中使用@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; }
(十).@FromHtml
10.1.註入HTML
自AndroidAnnotations2.2起
如果你要TextView中註入HTML文本(可能因為格式問題或者你天生喜歡使用HTML),有下面兩種方式幫到你:
- @FromHtml
- @HtmlRes
現在我們假設有以下的字符串資源
<!--[CDATA[HelloWorld!]]>
10.2.@HtmlRes
這個註解首先會表現成@StringRes(獲取字符串資源),然後進行包裝進行調用HTML.fromHtml():
@EActivity public classMyActivity extends Activity { // Injects R.string.hello_html @HtmlRes(R.string.hello_html) Spanned myHelloString; // Also injects R.string.hello_html @HtmlRes CharSequence helloHtml; }
10.3.@FromHtml
這個@FromHtml必須被使用在TextView,並且該TextView已經被@ViewById註解瞭,該註解的目的就是設置HTML文本在TextView上面
@EActivity public classMyActivity extends Activity { @ViewById(R.id.my_text_view) @FromHtml(R.string.hello_html) TextView textView; // Injects R.string.hello_html into theR.id.hello_html view @ViewById @FromHtml TextView helloHtml; }
(十一).@HttpsClient
自AndroidAnnotations2.6起
11.1.簡要介紹
通過@HttpsClient註解實例簡化瞭HTTPS請求配置秘鑰,信任庫和主機驗證。並且所有的參數都是可選的。
11.2.雙向認證
下面實例是一個完整的表單,如果你想實現驗證,方式如下:
@HttpsClient(trustStore=R.raw.cacerts, trustStorePwd=changeit, keyStore=R.raw.client, keyStorePwd=secret, allowAllHostnames=false) HttpClienthttpsClient;
- trustStore:信任庫
- trustStorePwd:密碼
- keyStore:秘鑰
- keyStorePwd:秘鑰密碼
- allowAllHostnames:允許的主機名
簡單的SSL身份認證如下:
@HttpsClient(trustStore=R.raw.mycacerts, trustStorePwd=changeit) HttpClienthttpsClient;
11.3.默認情況
如果你沒有指定信任的文件,註解會使用Android默認的信任庫在/system/etc/security/cacerts.bks
@HttpsClient HttpClienthttpsClient;
11.4.使用實例
@EActivity public classMyActivity extends Activity { @HttpsClient(trustStore=R.raw.cacerts, trustStorePwd=changeit, hostnameVerif=true) HttpClient httpsClient; @AfterInject @Background public void securedRequest() { try { HttpGet httpget = newHttpGet(https://www.verisign.com/); HttpResponse response =httpsClient.execute(httpget); doSomethingWithResponse(response); } catch (Exception e) { e.printStackTrace(); } } @UiThread public voiddoSomethingWithResponse(HttpResponse resp) { Toast.makeText(this, HTTP status + resp.getStatusLine().getStatusCode(), Toast.LENGTH_LONG).show(); } }
(十二).@NoConfigurationInstance
自AndroidAnnotations2.5開始
12.1.簡要介紹
當Configuration發生改變的時候,Activity通常會被銷毀然後重新創建。這樣會重新加載資源。這樣就涉及一個從就對象到新Activity實例的引用問題(例如:加載圖片,網絡連接,Activity運行的線程…)
這就是Activity.onRetainNonConfigurationInstance()用來解決這個問題。
12.2.@NonConfigurationInstance
我們通過@NonConfigurationInstance來對Activity的屬性變量進行註解,在配置信息發生改變的時候來保存實例。
@EActivity public classMyActivity extends Activity { @NonConfigurationInstance Bitmap someBitmap; @NonConfigurationInstance @Bean MyBackgroundTask myBackgroundTask; }
(十三).@RootContext
可以在@EBean依賴註入的類中使用@RootContext註入Android根組件,不過需要主要的時候隻能註入上下文相關類型的。
@EBean public class MyClass{ @RootContext Context context; // Only injected if the root context is anactivity @RootContext Activity activity; // Only injected if the root context is aservice @RootContext Service service; // Only injected if the root context is aninstance of MyActivity @RootContext MyActivity myActivity; }
(十四).@SystemService
自AndroidAnnotations1.0起
14.1.Android系統標準服務註入
使用標準的系統服務,我們需要記得系統服務的常量名字,然後進行強制轉換獲取。
notificationManager= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
14.2.@SystemService
使用@SystemSerivce註解的Activity中的屬性相當於使用Android系統服務,該等同於調用Context.getSystemService()方法。
@EActivity public classMyActivity extends Activity { @SystemService NotificationManager notificationManager; }
(十五).@ViewById
使用@ViewById註解Activity中的屬性等相當於佈局文件中的View組件。等同於調用findViewById()方法。該View的id可以設置在註解的參數中,例如@ViewById(R.id.myTextView)。如果沒有設置,將會使用字段的的名字。並且字段不能為私有的。實例如下:
@EActivity public classMyActivity extends Activity { // Injects R.id.myEditText @ViewById EditText myEditText; @ViewById(R.id.myTextView) TextView textView; }
(十六).@ViewsById
自AndroidAnnotations3.1起
該註解和@ViewById相似,不過該是註入一組視圖View。該私用java.util.List或者android.view.view子類型的屬性。該註解的參數值為R.id.*相關集合。在通過給定的IDs註入之後的views會保存在List中。但是需要檢查代碼避免空數據加入註入。
到此位置關於AndroidAnnotations註解Injection標簽使用方法已經全部講解完成瞭。