当前位置: 代码迷 >> Android >> 【FastDev4Android框架开发】AndroidAnnnotations流入框架使用之注入组件Components(九)
  详细解决方案

【FastDev4Android框架开发】AndroidAnnnotations流入框架使用之注入组件Components(九)

热度:505   发布时间:2016-04-27 22:22:35.0
【FastDev4Android框架开发】AndroidAnnnotations注入框架使用之注入组件Components(九)

 转载请标明出处: 

 http://blog.csdn.net/developer_jiangqq/article/details/49490083
 本文出自:【江清清的博客】


().前言:   

      前面我们已经对于AndroidAnnotations注入框架的基本介绍项目配置和运行原理做了讲解,今天我们开始具体学习怎么样使用这个框架。

     FastDev4Android框架项目地址:https://github.com/jiangqqlmj/FastDev4Android 

     本博客已完成下面相关注解方式更新:

     

().@EActivity:

      Activity被使用AndroidAnnotations进行注入的时候,我们需要使用@EActivity这个注入标签。这个标签的参数值必须是一个正确的layout ID(布局ID),该作为Activity的布局(Content View)。当然你也可以设置该参数值为空,这表示不设置content view。但是在绑定完成之前我们必须自己在onCreate()方法中设置布局(content view)

      使用方式如下:

@EActivity(R.layout.dragger_inject_layout)Public classAnnotationsTestActivity extends BaseActivity{}

  不使用布局ID的方法如下:

@EActivityPublic classMainActvityextends BaseActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
().@Application:

     3.1.基本使用

      AndroidAnnotations 2.2开始

      你可以使用@Application来对你的AndroidApplication类进行注解

@EApplicationpublicclassFDApplicationextendsApplication{}
  除了相关联的viewsextras之外,我们可以使用绝大多数AA注解。

@EApplicationpublic classMyApplication extends Application {  public void onCreate() {    super.onCreate();    initSomeStuff();  }  @SystemService  NotificationManager notificationManager;  @Bean  MyEnhancedDatastore datastore;  @RestService  MyService myService;  @OrmLiteDao(helper = DatabaseHelper.class,model = User.class)  UserDao userDao;  @Background  void initSomeStuff() {    // init some stuff in background  }}

 3.2.注入Application

 AndroidAnnotations 2.1开始

  你可以使用@App来进行注入Application

@EActivitypublic classMyActivity extends Activity {  @App  MyApplication application;}
该同样在任何类型注入组件中进行使用,例如:@EBBean

@EBeanpublic class MyBean{  @App  MyApplication application;}
().@EBean:

  4.1.注解自定义类

 我们可以对于非Android组件(例如:Activity,Service..)的类使用annotations,只需要使用@EBean来进行注解

@EBeanpublic class MyClass{}

【注】:使用@EBean注解的类必须只有一个构造函数,而且这个构造函数必须没有参数。或者在AndroidAnnotations2.7版本上面,该构造函数可以只有一个Context上下文引用类型的参数。

 4.2.注入类

 在另一个注解类或者Android组件中使用这个注解类,我们可以使用@Bean;

@EBeanpublic classMyOtherClass {  @Bean  MyClass myClass;}

同时你可以实现继承依赖关系

@EActivitypublic classMyActivity extends Activity {  @Bean  MyOtherClass myOtherClass;}

【注】当你在属性声明的地方使用@Bean注入,你总会得到一个新的实例,除非那个类是一个单例。

值得我们注意的是,注解生成的子类是final类型的,也就是说我们不能在继承生成的类。但是我们可以扩展原始的类。扩展出来的类同样可以使用注解。如下:

@EActivitypublic classMyChildActivity extends MyActivity {}
4.3.注入实现类

如果你想在代码中使用父类或者接口,那么你可以在@Bean注入的时候把实现类(implementation class)作为注入的参数值。

@EActivitypublic classMyActivity extends Activity {    /* A MyImplementation instance will beinjected.     * MyImplementation must be annotated [email protected] and implement MyInterface.     */    @Bean(MyImplementation.class)    MyInterface myInterface;}
4.4.支持的Annotations

在被@Ebean注解的类中,我们可以使用绝大多数AA(Android平台)Annotations

@EBeanpublic class MyClass{  @SystemService  NotificationManager notificationManager;  @UiThread  void updateUI() {  }}
4.5.支持的和View相关的Annotations

 在被@EBean注解的类中,我们可以使用和View相关的Annotations(例如:@View,@Click…)

@EBeanpublic class MyClass{  @ViewById  TextView myTextView;  @Click(R.id.myButton)  void handleButtonClick() {  }}
4.6.依赖注入之后回调执行相关代码

当我们@EBean注解的类的构造函数被执行的时候,它的属性还没有被注入(初始化),如果在构建的时候,想在依赖注入之后执行相关代码,你可以在一些方法上面使用@AfterInject Annotation,如下所示

@EBeanpublic class MyClass{  @SystemService  NotificationManager notificationManager;  @Bean  MyOtherClass dependency;  public MyClass() {    // notificationManager and dependency arenull  }  @AfterInject  public void doSomethingAfterInjection() {    // notificationManager and dependency areset  }}
4.7.作用域

AndroidAnnotations现在提供两种作用域实例

:的作用域:次创建都会创建一个新的实例对象

:单一用域:一次创建使用的时候会生成一个新实例,然后该实例会保持,其他都会使用同样的实例。

@EBean(scope =Scope.Singleton)public classMySingleton {}
().@EFragment:

  5.1.支持FragmentActivity注解

 AndroidAnnotations2.1版本开始

 AndroidAnnotations2.6版本之前,这是不支持Fragment注解,但是可以使用FragmentActivity来代替Activity.

@EActivity(R.id.main)public classDetailsActivity extends FragmentActivity {}
 5.2.Fragment支持

 AndroidAnnotations2.6版本开始

 AndroidAnnotations同时支持android.app.Fragmentandroid.support.v4.app.Fragment.并且它可以根据Fragment类型选择使用正确的APIs

 5.3.Fragment注解

 我们可以使用@EFragment来对Fragment进行注解.

@EFragmentpublic classMyFragment extends Fragment {}
AndroidAnnotations将会生成带有一个下划线的子类,例如:MyFragment_。当我们创建一个新的fragmetns实例的时候,你应该在xml布局文件中使用生成的子类,如下:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="fill_parent"   android:layout_height="fill_parent"    android:orientation="horizontal">     <fragment        android:id="@+id/myFragment"       android:name="com.company.MyFragment_"       android:layout_width="fill_parent"       android:layout_height="fill_parent" /> </LinearLayout>
创建如下:

MyFragmentfragment=new MyFragment_();

或者你可以使用构建器

MyFragmentfragmeng=MyFragment_.builder().build();

你同时可以在Fragment中使用各种其他类型的注解(annotations)

@EFragmentpublic classMyFragment extends Fragment {    @Bean    SomeBean someBean;    @ViewById    TextView myTextView;    @App    MyApplication customApplication;    @SystemService    ActivityManager activityManager;    @OrmLiteDao(helper = DatabaseHelper.class,model = User.class)    UserDao userDao;    @Click    void myButton() {    }    @UiThread    void uiThread() {    }    @AfterInject    void calledAfterInjection() {    }    @AfterViews    void calledAfterViewInjection() {    }    @Receiver(actions ="org.androidannotations.ACTION_1")    protected void onAction1() {    }}
5.4.Fragment布局

 Fragment获取view的标准的方法是重写onCreateView()方法

 @EFragmentpublic classMyFragment extends Fragment {    public View onCreateView(LayoutInflaterinflater, ViewGroup container, Bundle savedInstanceState) {        View view =inflater.inflate(R.layout.my_fragment_layout, container, false);        return view;    }}
你可以设置@EFragment的参数值,来让AndroidAnnotations来进行处理布局

@EFragment(R.layout.my_fragment_layout)public classMyFragment extends Fragment {}
如果你需要重写onCreateView()方法,例如因为你需要访问savedInstanceState,此时你仍然可以让AndroidAnnotations来处理布局创建,并且return null

@EFragment(R.layout.my_fragment_layout)public classMyFragment extends Fragment {    public View onCreateView(LayoutInflaterinflater, ViewGroup container, Bundle savedInstanceState) {        return null;    }}
5.5.注入Fragments

 我们可以在类中使用@EActivity@EFragment@Eview,@EViewGroup@EBean,使用@FragmentById或者@FragmentByTag来进行注入fragments

【注】推荐使用哪个@FragmentById而不是@FragmentByTag,因为后者没有编译时候的验证。

请注意@FragmentById@FragmentByTag仅仅能注入fragments而不是创建它们。所以它们只能存在于Activity

@EActivity(R.layout.fragments)public classMyFragmentActivity extends FragmentActivity {  @FragmentById  MyFragment myFragment;   @FragmentById(R.id.myFragment)  MyFragment myFragment2;   @FragmentByTag  MyFragment myFragmentTag;   @FragmentByTag("myFragmentTag")  MyFragment myFragmentTag2;}
5.6.DialogFragments

非常可惜的是,如果你使用@EFragment进行注入,你无法通过onCreteDialog()方法来创建一个Dialog新的实例。你应该调用super.onCreateDialog(),该该会返回一个Dialog实例。然后你可以一个@AfterViews注入的方法中设置views。

().@EProvider

    AndroidAnnotations2.4开始

    你可以使用@EProvider来对Android内容提供者进行注解。

@EProviderpublic classMyContentProvider extends ContentProvider { }
     除了相关viewsextras注解标签以外,我们还可以使用绝大多数注解。

@EProviderpublic classMyContentProvider extends ContentProvider {   @SystemService  NotificationManager notificationManager;   @Bean  MyEnhancedDatastore datastore;   @OrmLiteDao(helper = DatabaseHelper.class,model = User.class)  UserDao userDao;   @UiThread  void showToast() {   Toast.makeText(getContext().getApplicationContext(), "HelloWorld!", Toast.LENGTH_LONG).show();  }   // ...}
().@EReceiver

 7.1.注解广播接收者

 AndroidAnnotations2.4开始

 我们可以使用@EReceiver来对Android广播接受者进行注解

@EReceiverpublic classMyReceiver extends BroadcastReceiver { }
除了相关viewsextras以外,还可以使用绝大多数AA注解

@EReceiverpublic classMyReceiver extends BroadcastReceiver {   @SystemService  NotificationManager notificationManager;   @Bean  SomeObject someObject; }
 7.2.注解广播(Action)

 AndroidAnnotations3.2开始

 使用@ReceiverAction可以在一个被注解的广播接受者中简单处理广播

 一般情况下默认方法onReceive()来进行处理广播,但是我们可以通过@RecevierAction加入参数值来传递另外一个广播。

使用@ReceiverAction注解的方法可能存在以下这种参数类型:

  1. onReceiver(Contenxt context,Intent intent)中的context上下文引用
  2. onReceiver(Context context,Intent intent)中的intent
  3. 如果我们设置@ReceiverAction.Extra的值,任何被@ReceiverAction.Extra注解的本地android.os.Parcelable或者java.io.Serializable类型的参数。这些参数将会加入到intentextra中。加入intent.extra中的key的为@ReceiverAction.Extra中参数值。

 看如下例子:

@EReceiverpublic classMyIntentService extends BroadcastReceiver {    @ReceiverAction("BROADCAST_ACTION_NAME")    void mySimpleAction(Intent intent) {        // ...    }     @ReceiverAction    void myAction(@ReceiverAction.Extra StringvalueString, Context context) {        // ...    }     @ReceiverAction    voidanotherAction(@ReceiverAction.Extra("specialExtraName") StringvalueString, @ReceiverAction.Extra long valueLong) {        // ...    }     @Override    public void onReceive(Context context,Intent intent) {        // empty, will be overridden ingenerated subclass    }}
【注】因为BroadcastReceiveronRecevier是一个抽象方法,所以你不得不添加一个空方法的实现。为了方便起见,AndroidAnnotations框架已经提供AbstractBroadcastReceiver,该类已经实现了onReceiver()方法,所以你在使用的时候,可以不实现该方法。

【注】现在我们可以在@ReceiverAction参数中加入多个广播并进行处理,如下:

   @ReceiverAction({"MULTI_BROADCAST_ACTION1","MULTI_BROADCAST_ACTION2"})    void multiAction(Intent intent) {        // ...    }
7.3.数据结构(Data Schemes)

我们可以使用dataSchemes参数来设置一个或者多个数据来让Receiver进行处理

@EReceiverpublic classMyIntentService extends BroadcastReceiver {   @ReceiverAction(actions =android.content.Intent.VIEW, dataSchemes = "http")  protected void onHttp() {    // Will be called when an App wants to opena http website but not for https.  }   @ReceiverAction(actions =android.content.Intent.VIEW, dataSchemes = {"http","https"})  protected void onHttps() {    // Will be called when an App wants to opena http or https website.  } }
7.4.@Receiver注解说明

Activity.Fragment,Service,我们可以使用@Receiver注解,而不是直接声明一个BroadcastReceiver

@EActivitypublic classMyActivity extends Activity {   @Receiver(actions ="org.androidannotations.ACTION_1")  protected void onAction1() {   } }
().@EIntentService

AndroidAnnotations3.0开始

 我们可以使用@EIntentService注解的Android IntentService来处理@ServiceAction注解的方法中的Actions。对于此注解我们同样可以使用除views和extras以外的很多AA注解

@EIntentServicepublic classMyIntentService extends IntentService {     public MyIntentService() {        super("MyIntentService");    }     @ServiceAction    void mySimpleAction() {        // ...    }     @ServiceAction    void myAction(String param) {        // ...    }     @Override    protected void onHandleIntent(Intentintent) {        // Do nothing here    }}
我们可以使用内部构建器来启动IntentService

MyIntentService_.intent(getApplication())//    .myAction("test") //    .start();
如果在构建器重调用了多个Actions,那么只有最后一个action会被执行。

自AndroidAnnotations3.3开始

【注】因为IntentServiceonHandleIntent是一个抽象方法,所以你这边不得不添加一个空方法实现。为了方便起见这边提供了AbstractIntentService,该类实现了抽象方法。当你使用该类的时候,如果不需要你可以不用实现onHandleIntent

().@EService

 AndroidAnnotations2.4

 你可以使用@EService来进行注册Android Service

@EServicepublic classMyService extends Service {}
除了相关的viewsextras之外,同样可以使用绝大多数AA注解

@EServicepublic classMyService extends IntentService {   @SystemService  NotificationManager notificationManager;   @Bean  MyEnhancedDatastore datastore;   @RestService  MyRestClient myRestClient;   @OrmLiteDao(helper = DatabaseHelper.class,model = User.class)  UserDao userDao;   public MyService() {      super(MyService.class.getSimpleName());  }   @Override  protected void onHandleIntent(Intent intent){    // Do some stuff...     showToast();  }   @UiThread  void showToast() {    Toast.makeText(getApplicationContext(),"Hello World!", Toast.LENGTH_LONG).show();  }}
我们可以通过内部构建器来进行打开这个Service

MyService_.intent(getApplication()).start();
AndroidAnnotations3.0

同时内部构建器也提供stop()方法来进行停止该Service

MyService_.intent(getApplication()).stop();

 

().@EView

 10.1.注入自定义views

如果你想要创建自定义组件,我们可以使用@EView@EViewGroup来进行注解

 10.2.为什么要使用自定义组件?

在我们的APP中很多地方我们可能会复制同样的布局代码,并且我复制和调用相同的代码来控制这些布局。基于前面这些原因

,我们可以使用自定义组件来解决这些问题,让我们的工作变得更加轻松。

 10.3.使用@EView来注解自定义views

 AndroidAnnotations2.4

  我们只需要创建一个继承与View的新类,然后在这个View中就可以使用annotations了。

@EViewpublic classCustomButton extends Button {         @App        MyApplication application;         @StringRes        String someStringResource;     public CustomButton(Context context,AttributeSet attrs) {        super(context, attrs);    }}
现在你就可以在布局文件中使用这个View(【注】不要忘记"_")

<?xmlversion="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="match_parent"   android:layout_height="match_parent"    android:orientation="vertical">    <com.androidannotations.view.CustomButton_       android:layout_width="match_parent"       android:layout_height="wrap_content" />     <!-- ... --> </LinearLayout>
你也可以使用程序化创建方式

CustomButton button= CustomButton_.build(context);
 10.4.使用@EViewGroup来注解自定义ViewGroups

AndroidAnnotations2.2

.How to create it?

         首先我们需要为这个组件创建一个布局文件

<?xmlversion="1.0" encoding="utf-8"?><mergexmlns:android="http://schemas.android.com/apk/res/android" >     <ImageView        android:id="@+id/image"       android:layout_alignParentRight="true"       android:layout_alignBottom="@+id/title"       android:layout_width="wrap_content"       android:layout_height="wrap_content"        android:src="@drawable/check"/>     <TextView        android:id="@+id/title"       android:layout_toLeftOf="@+id/image"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:textColor="@android:color/white"        android:textSize="12pt" />     <TextView        android:id="@+id/subtitle"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:layout_below="@+id/title"        android:textColor="#FFdedede"        android:textSize="10pt" /> </merge>
【注】你有没有发现上面的merge标签?当这个布局被进行加载的时候,子节点会被直接加入到父节点中,这样就可以减少布局层级关系。

 正如你看到是这般使用了很多RelativeLayout特殊布局属性(layout_alignParentRight,layout_alignBottom,layout_toLeftOf,etc..),这是因为我知道这个布局会被加载到RelativeLayout中。

@EViewGroup(R.layout.title_with_subtitle)public classTitleWithSubtitle 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);    } }
就这样使用即可,是不是很简单呢?

现在让我们来看一下该怎么样使用这个自定义组件

.How to use it?

自定义组件和其他View控件一样,在布局文件中进行声明(【注】不要忘记控件名称最后的"_")

<pre name="code" class="html"><?xmlversion="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="match_parent"   android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical">    <com.androidannotations.viewgroup.TitleWithSubtitle_        android:id="@+id/firstTitle"       android:layout_width="match_parent"       android:layout_height="wrap_content" />    <com.androidannotations.viewgroup.TitleWithSubtitle_        android:id="@+id/secondTitle"       android:layout_width="match_parent"       android:layout_height="wrap_content" />    <com.androidannotations.viewgroup.TitleWithSubtitle_        android:id="@+id/thirdTitle"       android:layout_width="match_parent"       android:layout_height="wrap_content" /> </LinearLayout>


因为我们使用AA框架,所以我们会非常容易在Activity中得到这些注入的自定义组件并且去使用它。

@EActivity(R.layout.main)public class Mainextends Activity {     @ViewById    protected TitleWithSubtitle firstTitle,secondTitle, thirdTitle;     @AfterViews    protected void init() {         firstTitle.setTexts("decouple yourcode",                "Hide the component logicfrom the code using it.");         secondTitle.setTexts("write once,reuse anywhere",                "Declare you component inmultiple " +                "places, just as easily asyou " +                "would put a single basicView.");         thirdTitle.setTexts("Let's getstated!",                "Let's see howAndroidAnnotations can make it easier!");    }}
       在@EViewGroup注解的类中也同时支持绝大多数AndroidAnnotations注解方式,赶快去尝试使用吧。

到此位置关于AndroidAnnotations注解组件的方式和使用方法已经全部讲解完成了。

FastDev4Android项目已经添加配置了AndroidAnnotations框架,后期的框架项目中也会主要使用这个DI框架,.欢迎大家去Github站点进行clone或者下载浏览.

https://github.com/jiangqqlmj/FastDev4Android 

同时欢迎大家star和fork整个开源快速开发框架项目~如果有什么意见和反馈,欢迎留言,必定第一时间回复。也欢迎有同样兴趣的童鞋加入到该项目中来,一起维护该项目。

版权声明:本文为博主原创文章,未经博主允许不得转载。

1楼github_322208193天前 12:26
挺详细的,收藏一下。 最近也在使用AndroidAnnotations
  相关解决方案