从编者的角度来讲,annotations是一个减少代码编写量的一个工具,不是很建议去使用它
项目配置:
在项目build-gradle里面的配置:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2' // the latest version of the android-apt plugin classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4+' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files }
为什么android-apt是1.4+主要是想让studio去加载最新的脚本
在app里面的build-gradle的配置:
首先在配置顶端获取android-annotations的最新版本(红体字为准):
apply plugin: 'com.android.application'apply plugin: 'android-apt'
def AAVersion = '3.2+' // change this to your desired version, for example the latest stable: 3.2
然后配置apt:
apt {
arguments {
androidManifestFile variant.outputs[0].processResources.manifestFile
// if you have multiple outputs (when using splits), you may want to have other index than 0 resourcePackageName '这里填写项目名称' // If you're using Android NBS flavors you should use the following line instead of hard-coded packageName // resourcePackageName android.defaultConfig.packageName // You can set optional annotation processing options here, like these commented options: // logLevel 'INFO' // logFile '/var/log/aa.log' }
最后配置annotation的依赖:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:24.0.0'
apt "org.androidannotations:androidannotations:$AAVersion"
compile "org.androidannotations:androidannotations-api:$AAVersion"
配置就完成了,配置之后最好build一下项目
接下来直接上annotation的代码,值得注意的是在menifast.xml里面申明的activity已activity_为名字的activity然后build一下:
@activity
@EActivity(R.layout.activity_main)@Fullscreen@WindowFeature(Window.FEATURE_NO_TITLE)public class MainActivity extends AppCompatActivity {
@ViewById TextView hello; private RetrofitManage mInstantce; @AfterViews void init() {
hello.setText("bye_bye");
@fragment
示例:
1 2 3 | <pre class="brush:java;">@EFragment(R.layout.my_fragment_layout) public class MyFragment extends Fragment { }</pre> |
注册:
1 | <fragment android:id="@+id/myFragment" android:name="com.company.MyFragment_" android:layout_width="fill_parent" android:layout_height="fill_parent"></fragment> |
创建:
1 | MyFragment fragment = new MyFragment_(); |
普通类:
1 2 3 4 | @EBean public class MyClass {
} |
注意:这个类必须仅仅只能有一个构造函数,参数最多有一个context。
Activity中使用:
1 2 3 4 5 6 7 | @EActivity public class MyActivity extends Activity {
@Bean MyOtherClass myOtherClass;
} |
也可以用来声明接口:
1 2 | @Bean(MyImplementation.class) MyInterface myInterface; |
在普通类中还可以注入根环境:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @EBean public class MyClass {
@RootContext Context context;
// Only injected if the root context is an activity @RootContext Activity activity;
// Only injected if the root context is a service @RootContext Service service;
// Only injected if the root context is an instance of MyActivity @RootContext MyActivity myActivity;
} |
如果想在类创建时期做一些操作可以:
1 2 3 4 | @AfterInject public void doSomethingAfterInjection() { // notificationManager and dependency are set } |
单例类需要如下声明:
1 2 3 4 | @EBean(scope = Scope.Singleton) public class MySingleton {
} |
注意:在单例类里面不可以注入view和事件绑定,因为单例的生命周期比Activity和Service的要长,以免发生内存溢出。
@EView
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); } } |
注册:
1 | <com.androidannotations.view.custombutton_ android:layout_width="match_parent" android:layout_height="wrap_content"></com.androidannotations.view.custombutton_> |
创建:
1 | CustomButton button = CustomButton_.build(context); |
@EViewGroup
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @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); }
} |
注册:
1 | <com.androidannotations.viewgroup.titlewithsubtitle_ android:id="@+id/firstTitle" android:layout_width="match_parent" android:layout_height="wrap_content"></com.androidannotations.viewgroup.titlewithsubtitle_> |
@EApplication
1 2 3 4 | @EApplication public class MyApplication extends Application {
} |
Activity中使用:
1 2 3 4 5 6 7 | @EActivity public class MyActivity extends Activity {
@App MyApplication application;
} |
@EService
1 2 3 4 | @EService public class MyService extends Service {
} |
跳转service:
1 | MyService_.intent(getApplication()).start(); |
停止service:
1 | MyService_.intent(getApplication()).stop(); |
@EReceiver
1 2 3 4 | @EReceiver public class MyReceiver extends BroadcastReceiver {
} |
@Receiver 可以替代声明BroadcastReceiver
1 2 3 4 5 6 7 8 9 | @EActivity public class MyActivity extends Activity {
@Receiver(actions = "org.androidannotations.ACTION_1") protected void onAction1() {
}
} |
@EProvider
1 2 3 4 | @EProvider public class MyContentProvider extends ContentProvider {
} |
@ViewById
1 2 3 4 5 6 7 8 9 10 | @EActivity public class MyActivity extends Activity {
// Injects R.id.myEditText,变量名称必须和布局的id名称一致 @ViewById EditText myEditText;
@ViewById(R.id.myTextView) TextView textView; } |
@AfterViews
1 2 3 4 5 6 7 8 | @EActivity(R.layout.main) public class MyActivity extends Activity {
@ViewById TextView myTextView;
@AfterViews void updateTextWithDate() {<pre class="brush:java;">//一定要在这里进行view的一些设置,不要在oncreate()中设置,因为oncreate()在执行时 view还没有注入</pre> myTextView.setText("Date: " + new Date()); }[...] |
@StringRes
1 2 3 4 5 6 7 8 9 10 | @EActivity public class MyActivity extends Activity {
@StringRes(R.string.hello) String myHelloString;//不能设置成私有变量
@StringRes String hello;
} |
@ColorRes
1 2 3 4 5 6 7 8 9 10 | @EActivity public class MyActivity extends Activity {
@ColorRes(R.color.backgroundColor) int someColor;
@ColorRes int backgroundColor;
} |
@AnimationRes
1 2 3 4 5 6 7 8 9 10 | @EActivity public class MyActivity extends Activity {
@AnimationRes(R.anim.fadein) XmlResourceParser xmlResAnim;
@AnimationRes Animation fadein;
} |
@DimensionRes
1 2 3 4 5 6 7 8 9 10 | @EActivity public class MyActivity extends Activity {
@DimensionRes(R.dimen.fontsize) float fontSizeDimension;
@DimensionRes float fontsize;
} |
@DImensionPixelOffsetRes
1 2 3 4 5 6 7 8 9 10 | @EActivity public class MyActivity extends Activity {
@DimensionPixelOffsetRes(R.string.fontsize) int fontSizeDimension;
@DimensionPixelOffsetRes int fontsize;
} |
@DimensionPixelSizeRes
1 2 3 4 5 6 7 8 9 10 | @EActivity public class MyActivity extends Activity {
@DimensionPixelSizeRes(R.string.fontsize) int fontSizeDimension;
@DimensionPixelSizeRes int fontsize;
} |
其他的Res:
· @BooleanRes
· @ColorStateListRes
· @DrawableRes
· @IntArrayRes
· @IntegerRes
· @LayoutRes
· @MovieRes
· @TextRes
· @TextArrayRes
· @StringArrayRes
@Extra
·
1 2 3 4 5 6 7 8 9 10 | @EActivity public class MyActivity extends Activity {
@Extra("myStringExtra") String myMessage;
@Extra("myDateExtra") Date myDateExtraWithDefaultValue = new Date();
} |
·
或者:
·
1 2 3 4 5 6 7 | @EActivity public class MyActivity extends Activity {
// The name of the extra will be "myMessage",名字必须一致 @Extra String myMessage; } |
·
传值:
·
1 | MyActivity_.intent().myMessage("hello").start() ; |
·
@SystemService
·
1 2 3 4 5 6 | @EActivity public class MyActivity extends Activity {// @SystemService NotificationManager notificationManager;
} |
·
@HtmlRes
·
1 2 3 4 5 6 7 8 9 10 11 12 | @EActivity public class MyActivity extends Activity {
// Injects R.string.hello_html @HtmlRes(R.string.hello_html) Spanned myHelloString;
// Also injects R.string.hello_html @HtmlRes CharSequence helloHtml;
} |
·
@FromHtml
·
1 2 3 4 5 6 7 8 9 10 11 12 13 | @EActivity public class MyActivity extends Activity {//必须用在TextView
@ViewById(R.id.my_text_view) @FromHtml(R.string.hello_html) TextView textView;
// Injects R.string.hello_html into the R.id.hello_html view @ViewById @FromHtml TextView helloHtml;
} |
·
@NonConfigurationInstance
·
1 2 3 4 5 6 7 8 9 10 | public class MyActivity extends Activity {//等同于 Activity.onRetainNonConfigurationInstance()
@NonConfigurationInstance Bitmap someBitmap;
@NonConfigurationInstance @Bean MyBackgroundTask myBackgroundTask;
} |
·
@HttpsClient
·
1 2 | <pre class="brush:java;">@HttpsClient HttpClient httpsClient;</pre> |
·
示例:
·
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 | @EActivity public class MyActivity extends Activity {
@HttpsClient(trustStore=R.raw.cacerts, trustStorePwd="changeit", hostnameVerif=true) HttpClient httpsClient;
@AfterInject @Background public void securedRequest() { try { HttpGet httpget = new HttpGet("https://www.verisign.com/"); HttpResponse response = httpsClient.execute(httpget); doSomethingWithResponse(response); } catch (Exception e) { e.printStackTrace(); } }
@UiThread public void doSomethingWithResponse(HttpResponse resp) { Toast.makeText(this, "HTTP status " + resp.getStatusLine().getStatusCode(), Toast.LENGTH_LONG).show(); } } |
·
@FragmentArg
·
1 2 3 4 5 6 7 8 9 10 11 12 13 | @EFragment public class MyFragment extends Fragment {//等同于 Fragment Argument
@FragmentArg("myStringArgument") String myMessage;
@FragmentArg String anotherStringArgument;
@FragmentArg("myDateExtra") Date myDateArgumentWithDefaultValue = new Date();
} |
·
·
1 2 3 4 | MyFragment myFragment = MyFragment_.builder() .myMessage("Hello") .anotherStringArgument("World") .build(); |
·
@Click
·
1 2 3 4 5 6 7 8 9 10 11 12 | @Click(R.id.myButton) void myButtonWasClicked() { [...] } @Click void anotherButton() {//如果不指定则函数名和id对应 [...] } @Click void yetAnotherButton(View clickedView) { [...] } |
·
其他点击事件:
· Clicks with @Click
· Long clicks with @LongClick
· Touches with @Touch
AdapterViewEvents
·
· Item clicks with @ItemClick
· Long item clicks with @ItemLongClick
· Item selection with @ItemSelect 有两种方式调用: 1.
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @EActivity(R.layout.my_list) public class MyListActivity extends Activity {
// ...
@ItemClick public void myListItemClicked(MyItem clickedItem) {//MyItem是adapter的实体类,等同于adapter.getItem(position)
}
@ItemLongClick public void myListItemLongClicked(MyItem clickedItem) {
}
@ItemSelect public void myListItemSelected(boolean selected, MyItem selectedItem) {
}
} |
·
2.
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @EActivity(R.layout.my_list) public class MyListActivity extends Activity {
// ...
@ItemClick public void myListItemClicked(int position) {//位置id
}
@ItemLongClick public void myListItemLongClicked(int position) {
}
@ItemSelect public void myListItemSelected(boolean selected, int position) {
}
} |
·
@SeekBarProgressChange
·
1 | <pre class="brush:java;">//等同于SeekBar.OnSeekBarChangeListener.onProgressChanged(SeekBar, int, boolean)</pre> |
·
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @SeekBarProgressChange(R.id.seekBar) void onProgressChangeOnSeekBar(SeekBar seekBar, int progress, boolean fromUser) { // Something Here }
@SeekBarProgressChange(R.id.seekBar) void onProgressChangeOnSeekBar(SeekBar seekBar, int progress) { // Something Here }
@SeekBarProgressChange({R.id.seekBar1, R.id.seekBar2}) void onProgressChangeOnSeekBar(SeekBar seekBar) { // Something Here }
@SeekBarProgressChange({R.id.seekBar1, R.id.seekBar2}) void onProgressChangeOnSeekBar() { // Something Here }@SeekBarTouchStart and @SeekBarTouchStop |
·
@SeekBarTouchStart 和 @SeekBarTouchStop 接受开始和结束事件的监听
@TextChange
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @TextChange(R.id.helloTextView) void onTextChangesOnHelloTextView(CharSequence text, TextView hello, int before, int start, int count) { // Something Here }
@TextChange void helloTextViewTextChanged(TextView hello) { // Something Here }
@TextChange({R.id.editText, R.id.helloTextView}) void onTextChangesOnSomeTextViews(TextView tv, CharSequence text) { // Something Here }
@TextChange(R.id.helloTextView) void onTextChangesOnHelloTextView() { // Something Here } |
·
@BeforeTextChange
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @BeforeTextChange(R.id.helloTextView) void beforeTextChangedOnHelloTextView(TextView hello, CharSequence text, int start, int count, int after) { // Something Here }
@BeforeTextChange void helloTextViewBeforeTextChanged(TextView hello) { // Something Here }
@BeforeTextChange({R.id.editText, R.id.helloTextView}) void beforeTextChangedOnSomeTextViews(TextView tv, CharSequence text) { // Something Here }
@BeforeTextChange(R.id.helloTextView) void beforeTextChangedOnHelloTextView() { // Something Here } |
·
@AfterTextChange
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @AfterTextChange(R.id.helloTextView) void afterTextChangedOnHelloTextView(Editable text, TextView hello) { // Something Here }
@AfterTextChange void helloTextViewAfterTextChanged(TextView hello) { // Something Here }
@AfterTextChange({R.id.editText, R.id.helloTextView}) void afterTextChangedOnSomeTextViews(TextView tv, Editable text) { // Something Here }
@AfterTextChange(R.id.helloTextView) void afterTextChangedOnHelloTextView() { // Something Here } |
·
@OptionsMenu和OptionsItem
·
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 32 33 34 35 36 | @EActivity @OptionsMenu(R.menu.my_menu) public class MyActivity extends Activity {
@OptionMenuItem MenuItem menuSearch;
@OptionsItem(R.id.menuShare) void myMethod() { // You can specify the ID in the annotation, or use the naming convention }
@OptionsItem void homeSelected() { // home was selected in the action bar // The "Selected" keyword is optional }
@OptionsItem boolean menuSearch() { menuSearch.setVisible(false); // menuSearch was selected // the return type may be void or boolean (false to allow normal menu processing to proceed, true to consume it here) return true; }
@OptionsItem({ R.id.menu_search, R.id.menu_delete }) void multipleMenuItems() { // You can specify multiple menu item IDs in @OptionsItem }
@OptionsItem void menu_add(MenuItem item) { // You can add a MenuItem parameter to access it } } |
·
或者:
·
1 2 3 4 5 | @EActivity @OptionsMenu({R.menu.my_menu1, R.menu.my_menu2}) public class MyActivity extends Activity {
} |
·
@Background 执行:
·
1 2 3 4 5 6 7 8 | void myMethod() { someBackgroundWork("hello", 42); }
@Background void someBackgroundWork(String aParam, long anotherParam) { [...] } |
·
取消:
·
1 2 3 4 5 6 7 8 9 10 11 | void myMethod() { someCancellableBackground("hello", 42); [...] boolean mayInterruptIfRunning = true; BackgroundExecutor.cancelAll("cancellable_task", mayInterruptIfRunning); }
@Background(id="cancellable_task") void someCancellableBackground(String aParam, long anotherParam) { [...] } |
·
非并发执行:
·
1 2 3 4 5 6 7 8 9 10 | void myMethod() { for (int i = 0; i < 10; i++) someSequentialBackgroundMethod(i); }
@Background(serial = "test") void someSequentialBackgroundMethod(int i) { SystemClock.sleep(new Random().nextInt(2000)+1000); Log.d("AA", "value : " + i); } |
·
延迟:
·
1 2 3 | @Background(delay=2000) void doInBackgroundAfterTwoSeconds() { } |
·
@UiThread UI线程:
·
1 2 3 4 5 6 7 8 | void myMethod() { doInUiThread("hello", 42); }
@UiThread void doInUiThread(String aParam, long anotherParam) { [...] } |
·
延迟:
·
1 2 3 | @UiThread(delay=2000) void doInUiThreadAfterTwoSeconds() { } |
·
优化UI线程:
·
1 2 3 | @UiThread(propagation = Propagation.REUSE) void runInSameThreadIfOnUiThread() { } |
·
进度值改变:
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @EActivity public class MyActivity extends Activity {
@Background void doSomeStuffInBackground() { publishProgress(0); // Do some stuff publishProgress(10); // Do some stuff publishProgress(100); }
@UiThread void publishProgress(int progress) { // Update progress views }
} |
·
@OnActivityResult
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @OnActivityResult(REQUEST_CODE) void onResult(int resultCode, Intent data) { }
@OnActivityResult(REQUEST_CODE) void onResult(int resultCode) { }
@OnActivityResult(ANOTHER_REQUEST_CODE) void onResult(Intent data) { }
@OnActivityResult(ANOTHER_REQUEST_CODE) void onResult() { } |
·
以上的注释用法基本包含了平常程序中的事件绑定,用AndroidAnnotations框架可以专注于做逻辑开发,最主要是简化代码编写,容易维护。 如有问题可以参考官方文档https://github.com/excilys/androidannotations/wiki/Cookbook
activity中的使用:
@EActivity(R.layout.activity_main)@Fullscreen@WindowFeature(Window.FEATURE_NO_TITLE)public class MainActivity extends AppCompatActivity {
@ViewById TextView hello; private RetrofitManage mInstantce; @AfterViews void init() {
}