上一个博文讲了androidannotations的配置与使用,以及常见错误的解决方案。即:注解机制 androidannotations 让编程更随性,更轻松(一)
今天来详细地说明如何在代码中使用annotations进行注解。
关于注解的方法,官方文档的地址(英文好的朋友可以去尝试着学习一下):https://github.com/excilys/androidannotations/wiki/AvailableAnnotations
(PS:由于篇幅有限,这里只是介绍正常的用法,其实在使用注解时还需要注意一些细节性问题,如果大家遇到了什么问题,欢迎留言询问,我会及时给出合理的答案的(当然,在我能力之内的情况下~~))
下面我们一点一点来看:(这里会列出所有官方文档中给出的注解符号)
主要分为8个部分,咱们依次进行学习。
第一部分:Enhanced components
@Activity
@EActivity(R.layout.main)
//上面这句话的意思是:setContentView(R.layout.main);
public class MyActivity extends Activity {
}
@EActivity(R.id.main)
//FragmentActivity同理
public class DetailsActivity extends FragmentActivity {
}
@EApplation
@EApplication
//注解Applation这个类
public class MyApplication extends Application {
}
EBean
@EBean
//用这个符号来声明非android标准组件,比如自定义的一个class
//但是该类只能有一个构造方法,而且只能有一个参数(Context)或者是没有参数
public class MyClass {
}
@EFragment
@EFragment(R.layout.fragment)
public class MyFragment extends Fragment {
}
@ContentProvider
@EProvider
//注解另一大组件ContentProvider及其子类
public class MyContentProvider extends ContentProvider {
}
@EIntentService
@EIntentService
//对IntentService进行注解(IntentService继承自Service)
public class MyIntentService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
// Do nothing here
}
}
@EService
@EService
//Service,IntentService的亲爹...
public class MyService extends Service {
}
@EView && @EViewGroup
//自定义View(必须是继承自View或者是View的子类才行)
//这两个稍微有一点不同,即View和ViewGroup的不同
@EView
public class CustomButton extends Button {
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
@EViewGroup(R.layout.custonViewGroup)
//ViewGroup ....
public class CustomButton extends LinearLayout {
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
第二部分:Injection
@AfterExtras && @Extra
@EActivity
public class MyClass {
//这句话的意思是:getIntent().getStringExtra("someExtra")
@Extra("someExtra")
String someExtra;
//这句话的意思是:getIntent().getStringExtra("anotherExtra")
//注意:当没有指定参数名时,默认为int后的那个变量名,其他的同理
@Extra
int anotherExtra;
//加上这个注解,该函数将会在上面的@Extra执行完毕后获得执行的机会
@AfterExtras
public void doSomethingAfterExtrasInjection() {
// someExtra and anotherExtra are set to the value contained in the incoming intent
// if an intent does not contain one of the extra values the field remains unchanged
}
}
@AfterInject
@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
//只有这两个成员变量被初始化结束之后该函数才会被调用。
//和@AfterViews差不多哈,只不过这里是用在@EBean中的
}
}
@AfterViews
@EActivity(R.layout.main)
public class MyActivity extends Activity {
@ViewById
TextView myTextView;
@AfterViews
//加上这个注解的效果是:只有myTextView被findViewById()结束之后才会
//被调用,有效地避免了空指针情况的出现。
//这个和上面的@AfterInject都是等待变量初始化完毕再执行,不过等待的
//对象不同。
void updateTextWithDate() {
myTextView.setText("Date: " + new Date());
}
@App
//You can inject the application class using the
// @App annotation:
//用@APP来声明一个@EApplation类对象
@App
MyApplication application;
@FragmentById
@FragmentById(R.id.myFragment)
//对比@ViewById理解记忆...
MyFragment myFragment2;
@HtmlRes
//其实就是加载string.xml文件中的一个元素
//和@TextRes差不多
// Injects R.string.hello_html
@HtmlRes(R.string.hello_html)
Spanned myHelloString;
//Also injects R.string.hello_html
@HtmlRes
CharSequence helloHtml;
@FromHtml
@ViewById(R.id.my_text_view)
@FromHtml(R.string.hello_html)
//这句话的意思是setText(R.string.hello_html)
TextView textView;
@HttpsClient
//创建一个Client并配置参数
@HttpsClient(trustStore=R.raw.cacerts,
trustStorePwd="changeit",
keyStore=R.raw.client,
keyStorePwd="secret",
allowAllHostnames=false)
HttpClient httpsClient;
//当然,你也可以创建一个默认的客户端
@HttpsClient
HttpClient httpsClient;
@RootContext
@EBean
public class MyClass {
@RootContext
//等同于:content=getContext();
Context context;
// Only injected if the root context is an activity
@RootContext
//如果getActivity()存在的话,等同于activity=getActivity()
//如果getActivity()不存在,则不会执行
Activity activity;
// Only injected if the root context is a service
//同理
@RootContext
Service service;
}
@SystemService
//It is the same as calling the Context.getSystemService()
//method.翻译:等同于调用Context.getSystemService() 方法
@SystemService
NotificationManager notificationManager;
第三部分:Event binding
@TextChange
@TextChange(R.id.helloTextView)
//添加Text更改事件监听
//等效于:textView.addTextChangedListener(new TextWatcher());
void onTextChangesOnHelloTextView(CharSequence text, TextView hello, int before, int start, int count) {
//参数介绍:
//text:更改之后的字符串
//hello:被更改的对象,这里是TextView
//before:改变之前的字符串长度;
//start:更改后的字符串的起始位置
//count:被修改的字符串长度
//注意:这些参数可以根据自己的需要自行选择,不要求全部添加,根据需要而定
}
@BeforeTextChange
@BeforeTextChange(R.id.helloTextView)
//不用介绍了吧,和上一个是类似的,只不过这是改变前监听事件
void beforeTextChangedOnHelloTextView(TextView hello, CharSequence text, int start, int count, int after) {
}
@AfterTextChange
@AfterTextChange(R.id.helloTextView)
//同理...
void afterTextChangedOnHelloTextView(Editable text, TextView hello) {
// Something Here
}
@EditorAction
@EditorAction(R.id.helloTextView)
//最后一个,这种函数基本用不到,在这里提一下,保证完整性
void onEditorActionsOnHelloTextView(TextView hello, int actionId, KeyEvent keyEvent) {
// Something Here
}
@Click && @LongClick
//简单吧,点击事件监听
@Click(R.id.myButton)
void myButtonWasClicked() {
[...]
}
//持续点击事件监听
@Click(R.id.myButton)
void myButtonWasClicked() {
[...]
}
@ItemClick && @ItemLongClick && @ItemSelect
//别说你不会...
@ItemClick
public void myListItemClicked(MyItem clickedItem) {
}
@ItemLongClick
public void myListItemLongClicked(MyItem clickedItem) {
}
@ItemSelect
public void myListItemSelected(boolean selected, MyItem selectedItem) {
}
@SeekBarProgressChange && @SeekBarTouchStart &&@SeekBarTouchStop
//SeekBar拖动事件监听。简单,不说了...
@SeekBarProgressChange(R.id.seekBar)
void onProgressChangeOnSeekBar(SeekBar seekBar, int progress, boolean fromUser) {
// Something Here
}
@SeekBarProgressChange(R.id.seekBar)
void onProgressChangeOnSeekBar(SeekBar seekBar, int progress, boolean fromUser) {
// Something Here
}
@SeekBarProgressChange(R.id.seekBar)
void onProgressChangeOnSeekBar(SeekBar seekBar, int progress, boolean fromUser) {
// Something Here
}
第四部分:Threading
@Background
@Background
//新开一个线程去执行这里面的代码。
void someBackgroundWork(String aParam, long anotherParam) {
//这里的参数自定,没有什么要求
[...]
}
@UiThread
@UiThread
//运行在UI线程中,参数没什么要求
void doInUiThread(String aParam, long anotherParam) {
[...]
}
* @SupposeBackground*
@SupposeBackground
//这个也是在后台线程中运行的意思,但是比上一个更加智能,如果被一个UI线程
//调用后就会报一个异常,来给你一个提示。
void someMethodThatShouldNotBeCalledFromUiThread() {
//if this method will be called from the UI-thread an exception will be thrown
}
@SupposeBackground(serial = {"serial1", "serial2"})
//这个比上一个多了一点:就是执行这个函数的线程的id必须是指定的serial,
//如果线程的id不是这两个serial,即使是后台线程,也会报错。
void someMethodThatShouldBeCalledFromSerial1OrSerial2() {
//if this method will be called from another thread then a background thread with a
//serial "serial1" or "serial2", an exception will be thrown
}
//这里提一下:如果你想重写这个异常,可以通过如下方式:
//BackgroundExecutor.setWrongThreadListener();
@SupposeUiThread
@SupposeUiThread
//同理...
void someMethodThatShouldBeCalledOnlyFromUiThread() {
//if this method will be called from a background thread an exception will be thrown
}
//同样的:如果你想重写这个异常,可以通过如下方式:
//BackgroundExecutor.setWrongThreadListener();
第五部分:Misc
@InstanceState
@EActivity
public class MyActivity extends Activity {
//当此Activity被销毁时,会自动保存下面的两个变量。
//基本上还没用过...
@InstanceState
int someId;
@InstanceState
MySerializableBean bean;
}
@WindowFeature
@WindowFeature({ Window.FEATURE_NO_TITLE, Window.FEATURE_INDETERMINATE_PROGRESS })
@NoTitle
….
@Fullscreen
….
@CustomTitle
@CustomTitle(R.layout.custom_title)
//自定义Title,这平时根本用不到...
public class MyActivity extends Activity {
}
(啊,好多额,歇歇……..)