@EBean增强自定义类

来源:互联网 发布:mysql中的级联删除 编辑:程序博客网 时间:2024/06/15 05:22

原文地址:
https://github.com/excilys/androidannotations/wiki/Enhance-custom-classes

加强自定义类

您可以在一个不是一个标准的Android组件(如Activity,Service)的类使用注解@EBean。
你只需要使用@EBean注释这个类即可:

@EBeanpublic class MyClass {}

一个@EBean注解类必须只有一个构造函数。此构造必须不含参数,或者作为AndroidAnnotations2.7,它在有些语境中的可以有一个参数。

注射增强类

在另一个增强类或增强的Android组件使用增强类,则可以使用@Bean

@EBeanpublic class MyOtherClass {  @Bean  MyClass myClass;}

请注意链的依赖关系:

@EActivitypublic class MyActivity extends Activity {  @Bean  MyOtherClass myOtherClass;}

在使用@Bean时你总可以获得该类的一个新实例,除非这个类被声明为单例类(a Singleton)后面会讲到。

值得注意的是,生成的子类被加上了final限定,这意味着你不能扩展生成的子类。但是,您可以扩展原有的类和生成的代码将在子类中也同时发生扩展。这适用于每一个注解。
比如下面这个被注解的类,也会有一个子类的注入:

@EActivitypublic class MyChildActivity extends MyActivity {}

在代码区域注入一个接口的实现

如果你想通过其API(无论是超类或接口)来使用你的代码的依赖,可以作为注解@Bean的值参数指定的实现类。

@EActivitypublic class MyActivity extends Activity {    /* A MyImplementation instance will be injected.      * MyImplementation must be annotated with @EBean and implement MyInterface.     */    @Bean(MyImplementation.class)    MyInterface myInterface;}

这样有解耦的作用么?这里的类仍然知道它的依赖实现,但至少使用这些依赖的代码必须依靠API,这是一个有趣的目标。

支持其他注解的使用

您可以在@EBean类使用大多数AA标注:

@EBeanpublic class MyClass {  @SystemService  NotificationManager notificationManager;  @UiThread  void updateUI() {  }}

使用View相关的注解

您可以在@EBean类中使用视图相关的注释(@View,@Click…):

@EBeanpublic class MyClass {  @ViewById  TextView myTextView;  @Click(R.id.myButton)  void handleButtonClick() {  }}

注意:这里视图注解相关的控件myTextView和点击方法handleButtonClick() 只有在引用MyClass的Activity里包含相应内容视图中有这个myTextView id 和 R.id.myButton才有效。不然的话,myTextView会默认为空,而handleButtonClick()方法永远也不回被调用。

注射根上下文

你可以注入这就要看你@EBean类,使用@RootContext注解根的Android组件。请注意,它仅在上下文具有正确的类型情况下被注入。

@EBeanpublic 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;}

通过以下Activity引用的MyClass的实例,MyClass的(上文的)service将是null

@EActivitypublic class MyActivity extends Activity {  @Bean  MyClass myClass;}

依赖注入后执行代码

当你的@EBean注解类的构造函数被调用时,它的领域还没有被注入了呢。如果您需要在编译时执行代码,依赖注入之后,你应该对用一些方法使用@AfterInject注释。

@EBeanpublic class MyClass {  @SystemService  NotificationManager notificationManager;  @Bean  MyOtherClass dependency;  public MyClass() {    // notificationManager and dependency are null  }  @AfterInject  public void doSomethingAfterInjection() {    // notificationManager and dependency are set  }}

警告

如果一个父类和他的子类拥有同名的方法,这些方法被@AfterInject@AfterView 或者@AfterExtras 注解,那么就会出现BUG,详情请见 issue #810。
另外,虽然有关于当我们称之为@AfterViews保证顺序,-Inject或-Extras注解的方法,就不能保证每个具有相同方法名的@AfterXXX注解方法的调用顺序(参见问题#810)。
想知道这些注解之一的方法什么时候被调用,你可以在这里找到的答案。

Scopes

AndroidAnnotations目前支持两种范围:

  • 默认范围:在每次被注入的时候新生成一个类的实例对象;
  • 单例范围:在第一次被需要的时候创建一个Bean的实例,它然后被保留,并且在同一实例始终注入。

    @EBean(scope = Scope.Singleton)public class MySingleton {}

    注意:

    • 如果你的bean有一个Singleton范围,它只会保持一个参考应用程序上下文(应该使用context.getApplicationContext()),这是因为它的生活时间比任何Activity/Service 要长,所以它不应该保持一个参考任何此类的Android组件,以避免内存泄漏。
    • 我们还认为应该禁用与Singleton范围@EBean组件注入和查看事件的绑定,完全一样的原因(View参考一个Activity,因此它可能会造成内存泄漏)。
0 0