AndroidAnnotation
目录(?)[+]
- Enhance custom classes
- Enhancing custom classes 优化自定义类
- Injecting enhanced classes 注入优化的类
- Injecting implementations in assignable fields 注入实现到指定的字段
- Supported annotations 所支持的注解
- View related annotations 和视图相关的注解
- Injecting the root context 注入root context
- Executing code after dependency injection 在依赖注入后执行代码
- Scopes 作用域
- 本文档的简单示例下载
Enhance custom classes
Since AndroidAnnotations 2.4
Enhancing custom classes 优化自定义类
You can use annotations in a class that is not a standard Android component (such as an Activity, a Service).
你可以在一个不是标准Android组件(比如Activity,Service)的类中使用注解。
You just need to annotate it with
@EBean
:
你只需要使用
@EBean
进行注解:
@EBean public class MyClass { }
An@EBean
annotated class must have only one constructor. This constructor must either have no parameters, or, as ofAndroidAnnotations 2.7
, it may have one parameter of typeContext
.一个用@EBean
注解的类必须只有一个构造函数。这个构造函数必须是无参的,或者,在AndroidAnnotations 2.7
以后,可以带一个类型为Context
的参数。
Injecting enhanced classes 注入优化的类
To use this enhanced class in another enhanced class or in an enhanced Android component, use
@Bean
:
在其他优化类或者优化的Android组件中,加上
@Bean
注解就可以使用这个优化类。
@EBean public class MyOtherClass { @BeanMyClass myClass;}
Notice how you can chain dependencies:
请注意你怎么才能连接它们的相关性:
@EActivity public class MyActivity extends Activity { @BeanMyOtherClass myOtherClass;}
You always get a new instance when you use@Bean
on a field, unless that bean is a Singleton (see Scopes below).当你使用@Bean
在一个字段上时, 你一直获得一个新的实例。除非这个bean是一个单例(参看下面的作用域)。
It is worth noting that the generated subclasses are final, which means that you can't extend generated classes. However, you can extends original classes and generated code will be also generated for the child class. This works for every annotations.
值得注意的是,生成的子类是final类型的,这意味着你不能继承这些生成的子类。但是,你可以继承原始类,同时这些继承原始类的子类也会获得final子类生成的代码。
For example the following class will also have
myOtherClass
injected :
举个例子,下面这个类也会有
myOtherClass
注入进来:
@EActivity public class MyChildActivity extends MyActivity { }
Injecting implementations in assignable fields 注入实现到指定的字段
Since AndroidAnnotations 2.5
If you want to use a dependency in your code through its API (either a superclass or an interface), you can specify the implementation class as the value parameter of the
@Bean
annotation.
假如你想在代码中通过API使用一个依赖关系(不论是父类还是接口),你可以指定实现类作为
@Bean
注入的参数值。
@EActivity public class MyActivity extends Activity { /* A MyImplementation instance will be injected. * MyImplementation must be annotated with @EBean and implement MyInterface. */@Bean(MyImplementation.class)MyInterface myInterface;}
Does that provide decoupling advantages ? Well, the class still knows about its dependencies implementation, but at least the code using those dependencies has to rely on the API, which is an interesting goal.那样是不是提供了松耦合的优势呢?其实,这个类还是知道它自己的依赖实现,但是至少代码使用这些依赖必须依靠API,这其实是一个很有意思的目的。
Supported annotations 所支持的注解
You can use most AA annotations in an
@EBean
class:
你
可以
在
@EBean
类中使用大部分的AA注解:
@EBean public class MyClass { @SystemServiceNotificationManager notificationManager;@UiThreadvoid updateUI() { }}
View related annotations 和视图相关的注解
You can use view related annotations ( @View, @Click...) in your
@EBean
class:
你
可以
在
@EBean
类中
使用和视图相关
( @View
, @Click
...)
的注解:
@EBean public class MyClass { @ViewByIdTextView myTextView;@Click(R.id.myButton)void handleButtonClick() { }}
Notice that this will only work if the root Android component that depends onMyClass
is an activity with a layout that contains the needed views. Otherwise,myTextView
will be null, andhandleButtonClick()
will never be called.请注意,只有当依赖于MyClass
的Android根组件是一个activity,并且它的布局文件包含了所需的视图,这些注解才会生效。否则,myTextView
会为null,handleButtonClick()
也永远不会被调用。
Injecting the root context 注入root context
You can inject the root Android component that depends on your
@EBean
class, using the
@RootContext
annotation. Please notice that it only gets injected if the context has the right type.
你可以使用
@RootContext
注解注入依赖你
@EBean
类的Android根组件。请注意,只有当context的类型正确时,注入才会成功。
@EBean public class MyClass { @RootContextContext context;// Only injected if the root context is an activity@RootContextActivity activity;// Only injected if the root context is a service@RootContextService service;// Only injected if the root context is an instance of MyActivity@RootContextMyActivity myActivity;}
In the
MyClass
instance referenced by the following activity, the
service
field of
MyClass
(see above) will be
null
.
在下面这个activity中有一个上述的
MyClass
实例,它的字段
service
将为空。
@EActivity public class MyActivity extends Activity { @BeanMyClass myClass;}
Executing code after dependency injection 在依赖注入后执行代码
When the constructor of your
@EBean
annotated class is called, it's fields have not been injected yet. If you need to execute code at build time, after dependency injection, you should use the
@AfterInject
annotation on some methods.
当你的
@EBean
注解类的构造器被调用后,它的字段还没有注入进来。假如你需要在构建项目的时候执行代码,那么在依赖注入后,你需要添加使用
@AfterInject
注解的方法。
@EBean public class MyClass { @SystemServiceNotificationManager notificationManager;@BeanMyOtherClass dependency;public MyClass() { // notificationManager and dependency are null}@AfterInjectpublic void doSomethingAfterInjection() { // notificationManager and dependency are set}}
Note : If the parent and child classes have
@AfterViews
annotated methods with the same name, the generated code will be buggy. See issue #591 for more details.
注意:如果父类和子类的
@AfterViews
注解方法使用相同的名字,生成的代码会有bug。详情参见
issue #591
。
Scopes 作用域
Since AndroidAnnotations 2.5
AndroidAnnotations currently support two scopes:
AndroidAnnotations现在支持两个作用域:
- the default scope: a new bean instance is created each time a bean must be injected
- 默认作用域:每次当新的bean实例创建时都需要注入一个bean
- the singleton scope: a new instance of the bean is created the first time it is needed. It is then retained and the same instance is always injected.
- 单例作用域:只有第一次才创建bean实例。然后之后一直使用同一个实例注入。
@EBean(scope = Scope.Singleton) public class MySingleton { }
Caution警告
同样,我们也在使用
- If your bean has a
Singleton
scope, it will only keep a reference to the application context (usingcontext.getApplicationContext()
. That's because it lives longer than any activity / service, so it shouldn't keep a reference to any such Android component, to avoid memory leaks.- 假如你的bean有了
Singleton
作用域,它将保持application context的引用(使用context.getApplicationContext()
。那是因为它是生命周期比任何activity或者service都长,所以它应该在任何Android组件中保留引用,避免引起内存泄漏。- We also disable view injection and view event binding in
@EBean
components withSingleton
scope, for the exact same reason (views have a reference to the activity, which may therefore create a leak).Singleton
作用域的@EBean
组件中禁用了视图注入和视图事件绑定(视图拥有activity的引用,因此有可能产生内存泄漏)。
本文档的简单示例下载