Android Annotations 注解例子
1、AndroidAnnotations官网: http://androidannotations.org/ (也许你需要翻墙)
2、eclipse中使用androidannotations的配置方法说明:https://github.com/excilys/androidannotations/wiki/Eclipse-Project-Configuration
3、Android Studio中配置AndroidAnnotations:(这个是我这篇博文中要涉及到的!)
一、Android Studio配置androidannotations环境。
1、首先你建立一个module之后,在对应的app中会有一个名为build.gradle的文件(该module有效),而在整个项目外面也会有一个名为build.gradle的文件(全局有效)【这个工具中的application的目录下(相当于Eclipse下的workspace)是可以有多个module的(相当于Eclipse下的project)】
2、我们配置的时候大概要分为下面两步
在局部build.gradle中(加入 红色字体部分 ):
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
android {
compileSdkVersion 19
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "com.tongbu.mytest"
minSdkVersion 8
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:19.+'
apt "org.androidannotations:androidannotations:$AAVersion"
}
apt {
arguments {
androidManifestFile variant.processResources.manifestFile
resourcePackageName 'com.tongbu.mytest'
}
}
在全局build.gradle中(加入 红色字体部分 ):
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.+'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.3'
}
}
allprojects {
repositories {
jcenter()
}
}
如果以上的都顺利完成了,那么恭喜你已经快配置完了,还需要把AndroidManifest.xml中的Activity的名字后面加上 _(下划线),因为这个框架解析编译的时候,比如类MainActivity会被解析成MainActivity_.class,所以在清单文件中我们要在Activity的名字后面加一个下划线,或者androidannotation会报错!
但并不会这么顺利,在你补充完下划线之后,你会发现会提示你找不到MainActivity_这个东东
那么怎么办呢??我们说了它是在编译的时候整出来的,那我们只要按一下编译的按钮即可生成了!!
这样子androidannotation在android studio上的环境就配置好了
Android 最火快速开发框架AndroidAnnotations简介文章中的简单介绍,本篇注重讲解AndroidAnnotations中注解方法的使用。
@EActivity
示例:
@EActivity(R.layout.main)
public class MyActivity extends Activity { }
@fragment
示例:
@EFragment(R.layout.my_fragment_layout)
public class MyFragment extends Fragment {
}
注册:
<fragment
android:id="@+id/myFragment"
android:name="com.company.MyFragment_"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
创建:
MyFragment fragment = new MyFragment_();
普通类:
@EBean
public class MyClass { }
注意:这个类必须仅仅只能有一个构造函数,参数最多有一个context。
Activity中使用:
@EActivity
public class MyActivity extends Activity { @Bean
MyOtherClass myOtherClass; }
也可以用来声明接口:
@Bean(MyImplementation.class)
MyInterface myInterface;
在普通类中还可以注入根环境:
@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; }
如果想在类创建时期做一些操作可以:
@AfterInject
public void doSomethingAfterInjection() {
// notificationManager and dependency are set
}
单例类需要如下声明:
@EBean(scope = Scope.Singleton)
public class MySingleton { }
注意:在单例类里面不可以注入view和事件绑定,因为单例的生命周期比Activity和Service的要长,以免发生内存溢出。
@EView
@EView
public class CustomButton extends Button { @App
MyApplication application; @StringRes
String someStringResource; public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
注册:
<com.androidannotations.view.CustomButton_
android:layout_width="match_parent"
android:layout_height="wrap_content" />
创建:
CustomButton button = CustomButton_.build(context);
@EViewGroup
@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);
} }
注册:
<com.androidannotations.viewgroup.TitleWithSubtitle_
android:id="@+id/firstTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
@EApplication
@EApplication
public class MyApplication extends Application { }
@EActivity
public class MyActivity extends Activity { @App
MyApplication application; }
@EService
public class MyService extends Service { }
MyService_.intent(getApplication()).start();
MyService_.intent(getApplication()).stop();
@EReceiver
public class MyReceiver extends BroadcastReceiver { }
@EActivity
public class MyActivity extends Activity { @Receiver(actions = "org.androidannotations.ACTION_1")
protected void onAction1() { } }
@EProvider
public class MyContentProvider extends ContentProvider { }
@EActivity
public class MyActivity extends Activity { // Injects R.id.myEditText,变量名称必须和布局的id名称一致
@ViewById
EditText myEditText; @ViewById(R.id.myTextView)
TextView textView; @ViewByIds({R.id.id1,R.id.id2})
List<TextView> list;
}
@EActivity(R.layout.main)
public class MyActivity extends Activity { @ViewById
TextView myTextView; @AfterViews
void updateTextWithDate() {
//一定要在这里进行view的一些设置,不要在oncreate()中设置,因为oncreate()在执行时 view还没有注入
myTextView.setText("Date: " + new Date()); }[...]
@EActivity
public class MyActivity extends Activity { @StringRes(R.string.hello)
String myHelloString;//不能设置成私有变量 @StringRes
String hello; }
@EActivity
public class MyActivity extends Activity { @ColorRes(R.color.backgroundColor)
int someColor; @ColorRes
int backgroundColor; }
@EActivity
public class MyActivity extends Activity { @AnimationRes(R.anim.fadein)
XmlResourceParser xmlResAnim; @AnimationRes
Animation fadein; }
@EActivity
public class MyActivity extends Activity { @DimensionRes(R.dimen.fontsize)
float fontSizeDimension; @DimensionRes
float fontsize; }
@EActivity
public class MyActivity extends Activity { @DimensionPixelOffsetRes(R.string.fontsize)
int fontSizeDimension; @DimensionPixelOffsetRes
int fontsize; }
@EActivity
public class MyActivity extends Activity { @DimensionPixelSizeRes(R.string.fontsize)
int fontSizeDimension; @DimensionPixelSizeRes
int fontsize; }
@BooleanRes
@ColorStateListRes
@DrawableRes
@IntArrayRes
@IntegerRes
@LayoutRes
@MovieRes
@TextRes
@TextArrayRes
@StringArrayRes
@EActivity
public class MyActivity extends Activity { @Extra("myStringExtra")
String myMessage; @Extra("myDateExtra")
Date myDateExtraWithDefaultValue = new Date(); }
@EActivity
public class MyActivity extends Activity {
// The name of the extra will be "myMessage",名字必须一致
@Extra
String myMessage;
}
MyActivity_.intent().myMessage("hello").start() ;
@EActivity
public class MyActivity extends Activity {//
@SystemService
NotificationManager notificationManager;
}
@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;
}
@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; }
public class MyActivity extends Activity {//等同于 Activity.onRetainNonConfigurationInstance() @NonConfigurationInstance
Bitmap someBitmap; @NonConfigurationInstance
@Bean
MyBackgroundTask myBackgroundTask;
}
@HttpsClient
HttpClient httpsClient;
@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();
}
}
@EFragment
public class MyFragment extends Fragment {//等同于 Fragment Argument @FragmentArg("myStringArgument")
String myMessage; @FragmentArg
String anotherStringArgument; @FragmentArg("myDateExtra")
Date myDateArgumentWithDefaultValue = new Date();
}
MyFragment myFragment = MyFragment_.builder()
.myMessage("Hello")
.anotherStringArgument("World")
.build();
@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
有两种方式调用:
@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) { } }
@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) { } }
//等同于SeekBar.OnSeekBarChangeListener.onProgressChanged(SeekBar, int, boolean)
@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
@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(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(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
}
@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
}
}
@EActivity
@OptionsMenu({R.menu.my_menu1, R.menu.my_menu2})
public class MyActivity extends Activity { }
void myMethod() {
someBackgroundWork("hello", 42);
} @Background
void someBackgroundWork(String aParam, long anotherParam) {
[...]
}
void myMethod() {
someCancellableBackground("hello", 42);
[...]
boolean mayInterruptIfRunning = true;
BackgroundExecutor.cancelAll("cancellable_task", mayInterruptIfRunning);
} @Background(id="cancellable_task")
void someCancellableBackground(String aParam, long anotherParam) {
[...]
}
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);
}
@Background(delay=2000)
void doInBackgroundAfterTwoSeconds() {
}
void myMethod() {
doInUiThread("hello", 42);
} @UiThread
void doInUiThread(String aParam, long anotherParam) {
[...]
}
@UiThread(delay=2000)
void doInUiThreadAfterTwoSeconds() {
}
@UiThread(propagation = Propagation.REUSE)
void runInSameThreadIfOnUiThread() {
}
@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(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() {
}
Annotation 解析
1 运行时 Annotation 解析
(1) 运行时 Annotation 指 @Retention 为 RUNTIME 的 Annotation,可手动调用下面常用 API 解析
method.getAnnotation(AnnotationName.class);
method.getAnnotations();
method.isAnnotationPresent(AnnotationName.class);
其他 @Target 如 Field,Class 方法类似
getAnnotation(AnnotationName.class) 表示得到该 Target 某个 Annotation 的信息,因为一个 Target 可以被多个 Annotation 修饰
getAnnotations() 则表示得到该 Target 所有 Annotation
isAnnotationPresent(AnnotationName.class) 表示该 Target 是否被某个 Annotation 修饰
(2) 解析示例如下:
public static void main(String[] args) {
try {
Class cls = Class.forName("cn.trinea.java.test.annotation.App");
for (Method method : cls.getMethods()) {
MethodInfo methodInfo = method.getAnnotation(
MethodInfo.class);
if (methodInfo != null) {
System.out.println("method name:" + method.getName());
System.out.println("method author:" + methodInfo.author());
System.out.println("method version:" + methodInfo.version());
System.out.println("method date:" + methodInfo.date());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
以之前自定义的 MethodInfo 为例,利用 Target(这里是 Method)getAnnotation 函数得到 Annotation 信息,然后就可以调用 Annotation 的方法得到响应属性值
2 编译时 Annotation 解析
(1) 编译时 Annotation 指 @Retention 为 CLASS 的 Annotation,甴 apt(Annotation Processing Tool) 解析自动解析。需要做的
a. 自定义类集成自 AbstractProcessor
b. 重写其中的 process 函数
这块很多同学不理解,实际是 apt(Annotation Processing Tool) 在编译时自动查找所有继承自 AbstractProcessor 的类,然后调用他们的 process 方法去处理
(2) 假设之前自定义的 MethodInfo 的 @Retention 为 CLASS,解析示例如下:
@SupportedAnnotationTypes({ "cn.trinea.java.test.annotation.MethodInfo" })
public class MethodInfoProcessor extends AbstractProcessor { @Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
HashMap<String, String> map = new HashMap<String, String>();
for (TypeElement te : annotations) {
for (Element element : env.getElementsAnnotatedWith(te)) {
MethodInfo methodInfo = element.getAnnotation(MethodInfo.class);
map.put(element.getEnclosingElement().toString(), methodInfo.author());
}
}
return false;
}
}
SupportedAnnotationTypes 表示这个 Processor 要处理的 Annotation 名字。
process 函数中参数 annotations 表示待处理的 Annotations,参数 env 表示当前或是之前的运行环境
process 函数返回值表示这组 annotations 是否被这个 Processor 接受,如果接受后续子的 rocessor 不会再对这个 Annotations 进行处理
Android Annotations 注解例子的更多相关文章
- Android Studio配置Android Annotations框架详解--说说那些坑
我们开发过程中都需要写些findViewByid.serOnclickListener等类似的代码,虽然不费事,但是一个项目下来,工作量还是很大的.为了节省工作量,运生了很多对应的注解框架.网上的博客 ...
- Android注解使用之使用Support Annotations注解优化代码
前言: 前面学习总结了Java注解的使用,博客地址详见Java学习之注解Annotation实现原理,从本质上了解到什么注解,以及注解怎么使用?不要看见使用注解就想到反射会影响性能之类,今天我们就来学 ...
- Android简易注解View(java反射实现)
一.引言 Android中通过findViewById在布局文件中找到需要的View,加入一个Activity里面有许多的View需要初始化,那将是一件很繁琐的事情.当然Google一下你会发现有很多 ...
- Android Annotations Eclipse 配置 (3)
Android Annotations 本来我想写个 Java 版本的<RESTful客户端库:RestClient>用于 Android 应用开发,结果发现不太好写,虽然用了 Dynam ...
- Hibernate Annotations 注解
Hibernate Annotations 注解 对于org.hibernate.annotations与org.hibernate.persistence,它的注释比如Columns,可是不知道怎么 ...
- Android Annotations浅析
这阵子遇到了好多事情,挺久没来更新博文了,这两天在学这个开源框架Android Annotations,用起来感觉挺方便的, 相信用过Spring注解的孩子理解起来应该比較easy! 就是配置起来比較 ...
- [Android Pro] 完美Android Cursor使用例子(Android数据库操作)
reference to : http://www.ablanxue.com/prone_10575_1.html 完美 Android Cursor使用例子(Android数据库操作),Androi ...
- 使用Android Annotations开发
使用Android Annotations框架gradle配置1.修改Module下的build.gradle apply plugin: 'com.android.application' appl ...
- Android MediaCodec 使用例子
Android MediaCodec 使用例子 下面的例子是使用MediaCodec 录制到文件的例子. 1 public class AvcEncoder { private MediaCodec ...
随机推荐
- Java中替换HTML标签的方法代码
这篇文章主要介绍了Java中替换HTML标签的方法代码,需要的朋友可以参考下 replaceAll("\\&[a-zA-Z]{0,9};", "").r ...
- [百科] - SIP(会话发起协议)
SIP(会话发起协议)SIP是类似于HTTP的基于文本的协议.SIP可以减少应用特别是高级应用的开发时间.由于基于IP协议的SIP利用了IP网络,固定网运营商也会逐渐认识到SIP技术对于他们的深远意义 ...
- 序号自增key的使用
由于在模板中,需要输出序号,但是从数据库中提取的话,保证不了序号的连续性. 在模板中我就使用foreach循环,查手册看到foreach的使用 但是我还是没从手册中学会key的使用.尝试使用 结果,如 ...
- Wps 方框里面加勾
1.选择插入-->选择符号 2.选择更多 3.选择 字体Wingdings 然后下拉到最后.就看到了
- 红,X-Japan
ktv如果唱这首应该很爽,慢慢学. 红(くれない) 歌手:X JAPAN作词:YOSHIKI作曲:YOSHIKI I could not look back you'd gone away from ...
- mysql主从复制 主主复制 读写分离
首先是mysql的主从复制很简单 主主复制也就是互相主从最麻烦的最难的就是日志恢复,增量恢复什么的比较复杂 首先如果你不会安装mysql版本最好一样,或者往上的版本,因为mysql是向下兼容 请注意不 ...
- JDBC链接数据库版本三,使用C3P0,使用jar文件两个
JdbcUtil类: package com.xiaohui.jdbc.util; import java.sql.Connection; import java.sql.PreparedStatem ...
- word 使用宏批量设置表格
Sub ChangeTable() Application.Browser.Target = wdBrowseTable To ActiveDocument.Tables.Count ActiveDo ...
- intervention/image intervention/imagecache
http://image.intervention.io/ 安装两个包 composer require intervention/image composer require interventio ...
- Operand forms
Operand forms Computer Systems A Programmer's Perspective Second Edition