AndroidAnnotations——Enhance custom classes 优化自定义类

翻译 2013年12月04日 16:42:30

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 of AndroidAnnotations 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 {

  @Bean
  MyClass myClass;

}

Notice how you can chain dependencies:
请注意你怎么才能连接它们的相关性:

@EActivity
public class MyActivity extends Activity {

  @Bean
  MyOtherClass myOtherClass;

}
You always get a new instance when you use @Bean on a field, unless that bean is aSingleton (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 {

  @SystemService
  NotificationManager notificationManager;

  @UiThread
  void updateUI() {

  }

}

View related annotations 和视图相关的注解


You can use view related annotations (@View@Click...) in your @EBean class:
可以 @EBean 类中使用和视图相关 (@View@Click...) 的注解:

@EBean
public class MyClass {

  @ViewById
  TextView myTextView;

  @Click(R.id.myButton)
  void handleButtonClick() {

  }

}
Notice that this will only work if the root Android component that depends on MyClass 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 {

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

}

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 {

  @Bean
  MyClass 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 {

  @SystemService
  NotificationManager notificationManager;

  @Bean
  MyOtherClass dependency;

  public MyClass() {
    // notificationManager and dependency are null
  }

  @AfterInject
  public 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 (using context.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的引用,因此有可能产生内存泄漏)。

本文档的简单示例下载

相关文章推荐

AndroidAnnotations——Enhance custom views 优化自定义组件

Enhance custom views 优化自定义组件 @EView and @EViewGroup are the annotations to use if you want to c...

Unity/UI —— 使用字符图片自定义字体(Custom Font)

在Unity的UI设计中,我们经常会遇到需要自定义字体的情况。毕竟Unity自带的字体只有Arial一种,根本无法满足人民群众对于美的向往。当然,全能的Unity支持我们导入或创建字体,并可以在GUI...

vici mvc开发第九篇——Custom Controls(自定义控件)

一、Creating a custom control classvici mvc框架容许你创建自己的控件,这些控件你可以在任何时候调用,也可以绑定到任何一个窗体,当然这个窗体必须与控件建立一些关系。...

Custom Animation——自定义动画

This example shows how to use postcompose and vectorContext to animate features. Here we choose ...

Custom Icon——自定义图标

This example creates a custom element for the attribution icon. 这个例子用来为attribution控件的图标创建一个自定义的元素。 ...

Custom Interactions——自定义交互式控件

This example demonstrates creating a custom interaction by subclassing ol.interaction.Pointer. Note ...

Custom Controls——自定义控件

This example creates a "rotate to north" button. 这个例子用来创建一个“旋转到北”的按钮。 代码: Custom Con...

.Net——自定义特性(Custom Attributes)的创建与查看

有时候,我们会看到这样的东西放在类或者方法上面:                [Obsolete("请更新方法")]                     刚开始...

自定义现有类(Customizing Existing Classes)

对象应该有明确定义的任务,例如构建具体信息、显示视觉内容或者控制信息流动。一个类接口定义其他与对象相互作用的方式,帮助对象完成这些任务。 有时候,你会发现通过添加行为来扩展现有类只有在某些情况下有用。...

使用Custom Control自定义控件

  • 2010年07月01日 09:43
  • 66KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AndroidAnnotations——Enhance custom classes 优化自定义类
举报原因:
原因补充:

(最多只允许输入30个字)