AndroidAnnnotations注入框架使用之注入组件Components(三)

(一).前言:
前面咱们已经对于AndroidAnnotations注入框架的基本介绍项目配置和运行原理作了讲解,今天咱们开始具体学习怎么样使用这个框架。
(二).@EActivity:
当Activity被使用AndroidAnnotations进行注入的时候,咱们须要使用@EActivity这个注入标签。这个标签的参数值必须是一个正确的layout ID(布局ID),该做为Activity的布局(Content View)。固然你也能够设置该参数值为空,这表示不设置content view。可是在绑定完成以前咱们必须本身在onCreate()方法中设置布局(content view)
使用方式以下:java

1
2android

@EActivity(R.layout.dragger_inject_layout)
Public class AnnotationsTestActivity extends BaseActivity{}web

不使用布局ID的方法以下:数据结构

1
2
3
4
5
6
7app

@EActivity
public class MainActvityextends BaseActivity{
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}框架

(三).@Application:
3.1.基本使用
自AndroidAnnotations 2.2开始
你可使用@Application来对你的Android Application类进行注解ide

1
2函数

@EApplication
public class FDApplication extendsApplication{}布局

除了相关联的views和extras以外,咱们可使用绝大多数AA注解。学习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

@EApplication
public class MyApplication 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类

1
2
3
4
5

@EActivity
public class MyActivity extends Activity {
  @App
  MyApplication application;
}

该一样在任何类型注入组件中进行使用,例如:@EBBean

1
2
3
4
5

@EBean
public class MyBean {
  @App
  MyApplication application;
}

(四).@EBean:
4.1.注解自定义类
咱们能够对于非Android组件(例如:Activity,Service..)的类使用annotations,只须要使用@EBean来进行注解

1
2
3

@EBean
public class MyClass {
}

【注】:使用@EBean注解的类必须只有一个构造函数,并且这个构造函数必须没有参数。或者在AndroidAnnotations2.7版本上面,该构造函数能够只有一个Context上下文引用类型的参数。
4.2.注入类
在另外一个注解类或者Android组件中使用这个注解类,咱们可使用@Bean;

1
2
3
4
5

@EBean
public class MyOtherClass {
  @Bean
  MyClass myClass;
}

同时你能够实现继承依赖关系

1
2
3
4
5

@EActivity
public class MyActivity extends Activity {
  @Bean
  MyOtherClass myOtherClass;
}

【注】当你在属性声明的地方使用@Bean注入,你总会获得一个新的实例,除非那个类是一个单例。
值得咱们注意的是,注解生成的子类是final类型的,也就是说咱们不能在继承生成的类。可是咱们能够扩展原始的类。扩展出来的类一样可使用注解。以下:

1
2
3

@EActivity
public class MyChildActivity extends MyActivity {
}

4.3.注入实现类
若是你想在代码中使用父类或者接口,那么你能够在@Bean注入的时候把实现类(implementation class)做为注入的参数值。

1
2
3
4
5
6
7
8

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

4.4.支持的Annotations
在被@Ebean注解的类中,咱们可使用绝大多数AA(Android平台) 的Annotations;

1
2
3
4
5
6
7
8

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

4.5.支持的和View相关的Annotations
在被@EBean注解的类中 ,咱们可使用和View相关的Annotations(例如:@View,@Click…)

1
2
3
4
5
6
7
8

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

4.6.依赖注入以后回调执行相关代码
当咱们@EBean注解的类的构造函数被执行的时候,它的属性尚未被注入(初始化),若是在构建的时候,想在依赖注入以后执行相关代码,你能够在一些方法上面使用@AfterInject Annotation,以下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14

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

4.7.做用域
AndroidAnnotations如今提供两种做用域实例
①:默认的做用域:每次建立都会建立一个新的实例对象
②:单一做用域:第一次建立使用的时候会生成一个新实例,而后该实例会保持,其余都会使用一样的实例。

1
2
3

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

(五).@EFragment:
5.1.支持FragmentActivity注解
从AndroidAnnotations2.1版本开始
在AndroidAnnotations2.6版本以前,这是不支持Fragment注解,可是可使用FragmentActivity来代替Activity.

1
2
3

@EActivity(R.id.main)
public class DetailsActivity extends FragmentActivity {
}

5.2.Fragment支持
从AndroidAnnotations2.6版本开始
AndroidAnnotations同时支持android.app.Fragment和android.support.v4.app.Fragment.而且它能够根据Fragment类型选择使用正确的APIs
5.3.Fragment注解
咱们可使用@EFragment来对Fragment进行注解.

1
2
3

@EFragment
public class MyFragment extends Fragment {
}

AndroidAnnotations将会生成带有一个下划线的子类,例如:MyFragment_。当咱们建立一个新的fragmetns实例的时候,你应该在xml 布局文件中使用生成的子类,以下:

1
2
3
4
5
6
7
8
9
10
11

<linearlayout xmlns: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>

建立以下:

1

MyFragment fragment=new MyFragment_();

或者你可使用构建器

1

MyFragment fragmeng=MyFragment_.builder().build();

你同时能够在Fragment中使用各类其余类型的注解(annotations)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

@EFragment
public class MyFragment 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()方法

1
2
3
4
5
6
7

@EFragment
public class MyFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
        return view;
    }
}

你能够设置@EFragment的参数值,来让AndroidAnnotations来进行处理布局

1
2
3

@EFragment(R.layout.my_fragment_layout)
public class MyFragment extends Fragment {
}

若是你须要重写onCreateView()方法,例如由于你须要访问savedInstanceState,此时你仍然可让AndroidAnnotations来处理布局建立,而且return null

1
2
3
4
5
6

@EFragment(R.layout.my_fragment_layout)
public class MyFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return null;
    }
}

5.5.注入Fragments
咱们能够在类中使用@EActivity,@EFragment,@Eview,@EViewGroup,@EBean,使用@FragmentById或者@FragmentByTag来进行注入fragments。
【注】推荐使用哪一个@FragmentById而不是@FragmentByTag,由于后者没有编译时候的验证。
请注意@FragmentById和@FragmentByTag仅仅能注入fragments而不是建立它们。因此它们只能存在于Activity中

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@EActivity(R.layout.fragments)
public class MyFragmentActivity 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内容提供者进行注解。

1
2
3

@EProvider
public class MyContentProvider extends ContentProvider {
}

除了相关views和extras注解标签之外,咱们还可使用绝大多数注解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

@EProvider
public class MyContentProvider extends ContentProvider {

  @SystemService
  NotificationManager notificationManager;

  @Bean
  MyEnhancedDatastore datastore;

  @OrmLiteDao(helper = DatabaseHelper.class, model = User.class)
  UserDao userDao;

  @UiThread
  void showToast() {
    Toast.makeText(getContext().getApplicationContext(), "Hello World!", Toast.LENGTH_LONG).show();
  }
  // ...
}

(七).@EReceiver
7.1.注解广播接收者
自AndroidAnnotations2.4开始
咱们可使用@EReceiver来对Android广播接受者进行注解

1
2
3

@EReceiver
public class MyReceiver extends BroadcastReceiver {
}

除了相关views和extras之外,还可使用绝大多数AA注解

1
2
3
4
5
6
7
8
9
10

@EReceiver
public class MyReceiver 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类型的参数。这些参数将会加入到intent得extra中。加入intent.extra中的key的为@ReceiverAction.Extra中参数值。

看以下例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@EReceiver
public class MyIntentService extends BroadcastReceiver {

    @ReceiverAction("BROADCAST_ACTION_NAME")
    void mySimpleAction(Intent intent) {
        // ...
    }

    @ReceiverAction
    void myAction(@ReceiverAction.Extra String valueString, Context context) {
        // ...
    }

    @ReceiverAction
    void anotherAction(@ReceiverAction.Extra("specialExtraName") String valueString, @ReceiverAction.Extra long valueLong) {
        // ...
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // empty, will be overridden in generated subclass
    }
}

【注】由于BroadcastReceiver的onRecevier是一个抽象方法,因此你不得不添加一个空方法的实现。为了方便起见,AndroidAnnotations框架已经提供AbstractBroadcastReceiver ,该类已经实现了onReceiver()方法,因此你在使用的时候,能够不实现该方法。
【注】如今咱们能够在@ReceiverAction参数中加入多个广播并进行处理,以下:

1
2
3
4

@ReceiverAction({"MULTI_BROADCAST_ACTION1", "MULTI_BROADCAST_ACTION2"})
void multiAction(Intent intent) {
// ...
}

7.3.数据结构(Data Schemes)
咱们可使用dataSchemes参数来设置一个或者多个数据来让Receiver进行处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@EReceiver
public class MyIntentService extends BroadcastReceiver {

  @ReceiverAction(actions = android.content.Intent.VIEW, dataSchemes = "http")
  protected void onHttp() {
    // Will be called when an App wants to open a 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 open a http or https website.
  }

}

7.4.@Receiver注解说明
在Activity.Fragment,Service,咱们可使用@Receiver注解,而不是直接声明一个BroadcastReceiver

1
2
3
4
5
6

@EActivity
public class MyActivity extends Activity {
  @Receiver(actions = "org.androidannotations.ACTION_1")
  protected void onAction1() {
  }
}

(八).@EIntentService
自AndroidAnnotations3.0开始
咱们可使用@EIntentService注解的Android IntentService来处理@ServiceAction注解的方法中的Actions。对于此注解咱们一样可使用除views和extras之外的不少AA注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

@EIntentService
public class MyIntentService extends IntentService {

    public MyIntentService() {
        super("MyIntentService");
    }

    @ServiceAction
    void mySimpleAction() {
        // ...
    }

    @ServiceAction
    void myAction(String param) {
        // ...
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // Do nothing here
    }
}

咱们可使用内部构建器来启动IntentService

1
2
3

MyIntentService_.intent(getApplication())
.myAction("test")
.start();

若是在构建器重调用了多个Actions,那么只有最后一个action会被执行。
自AndroidAnnotations3.3开始
【注】由于IntentService的onHandleIntent是一个抽象方法,因此你这边不得不添加一个空方法实现。为了方便起见这边提供了AbstractIntentService,该类实现了抽象方法。当你使用该类的时候,若是不须要你能够不用实现onHandleIntent。
(九).@EService
自AndroidAnnotations2.4起
你可使用@EService来进行注册Android Service

1
2
3

@EService
public class MyService extends Service {
}

除了相关的views和extras以外,一样可使用绝大多数AA注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

@EService
public class MyService 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

1

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

自AndroidAnnotations3.0起
同时内部构建器也提供stop()方法来进行中止该Service

1

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

(十).@EView
10.1.注入自定义views
若是你想要建立自定义组件,咱们可使用@EView和@EViewGroup来进行注解
10.2.为何要使用自定义组件?
在咱们的APP中不少地方咱们可能会复制一样的布局代码,而且我复制和调用相同的代码来控制这些布局。基于前面这些缘由
,咱们可使用自定义组件来解决这些问题,让咱们的工做变得更加轻松。
10.3.使用@EView来注解自定义views
自AndroidAnnotations2.4起
咱们只须要建立一个继承与View的新类,而后在这个View中就可使用annotations了。

1
2
3
4
5
6
7
8
9
10
11
12
13

@EView
public class CustomButton extends Button {

        @App
        MyApplication application;

        @StringRes
        String someStringResource;

    public CustomButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

如今你就能够在布局文件中使用这个View了(【注】不要忘记"_")

1
2
3
4
5
6
7
8
9
10
11
12
13

< ?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns: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>

你也可使用程序化建立方式

1

CustomButton button = CustomButton_.build(context);

10.4.使用@EViewGroup来注解自定义ViewGroups
自AndroidAnnotations2.2起
①.How to create it?
首先咱们须要为这个组件建立一个布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

< ?xml version="1.0" encoding="utf-8"?>
<merge xmlns: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中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

@EViewGroup(R.layout.title_with_subtitle)
public class TitleWithSubtitle 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控件同样,在布局文件中进行声明(【注】不要忘记控件名称最后的"_")

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

< ?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns: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中获得这些注入的自定义组件而且去使用它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

@EActivity(R.layout.main) public class Main extends Activity {     @ViewById     protected TitleWithSubtitle firstTitle, secondTitle, thirdTitle;     @AfterViews     protected void init() {         firstTitle.setTexts("decouple your code",                 "Hide the component logic from the code using it.");         secondTitle.setTexts("write once, reuse anywhere",                 "Declare you component in multiple " +                 "places, just as easily as you " +                 "would put a single basic View.");         thirdTitle.setTexts("Let's get stated!",                 "Let's see how AndroidAnnotations can make it easier!");     } }

相关文章
相关标签/搜索