美文网首页Android开发技能知识点
Android Annotation 注解框架

Android Annotation 注解框架

作者: 黄海佳 | 来源:发表于2017-03-20 10:19 被阅读998次
    一、Annotation简单介绍

    AndroidAnnotations是一个能够让你快速进行Android开发的注释、注解开源框架。使代码更加精简,使项目更加容易维护,与相比原生的Android开发,能够让你少些很多代码。原理是给某个东西打上一个身份标识,告诉ide说,这个东西是要进行id绑定的,那个东西是参数来着。。。
    官网如下:官网

    Annotation的主要完成的工作如下

    1、使用依赖注入(Dependency Injection)

    2、简化的线程模型(Simplified threading model)

    3、事件绑定(Event binding)

    4、REST Client

    5、No Magic

    Paste_Image.png
    二、相关专有名词解释
    1. 元数据(metadata)

    元数据由metadata译来,所谓的元数据就是“关于数据的数据”,更通俗的说就是描述数据的数据,对数据及信息资源的描述性信息.比如说一个文本文件,有创建时间,创建人,文件大小等数据,这都可以理解为是元数据。

    在java中,元数据以标签的形式存在java代码中,它的存在并不影响程序代码的编译和执行,通常它被用来生成其它的文件或运行时知道被运行代码的描述信息。java当中的javadoc和注解都属于元数据。

    2 元注解

    元注解就是定义注解的注解,是java提供给我们用于定义注解的基本注解.在java.lang.annotation包中我们可以看到目前元注解共有以下几个。
    @Retention
    @Target
    @Inherited
    @Documented
    @interface

    3. 注解处理器

    注解处理器是javac的一个工具,它用来在编译时扫描和处理注解(Annotation)。你可以自定义注解,并注册到相应的注解处理器,由注解处理器来处理你的注解。一个注解的注解处理器,以Java代码(或者编译过的字节码)作为输入,生成文件(通常是.java文件)作为输出。这些生成的Java代码是在生成的.java文件中,所以你不能修改已经存在的Java类,例如向已有的类中添加方法。这些生成的Java文件,会同其他普通的手动编写的Java源代码一样被javac编译。

    三、Annotation相关方法

    Annotation支持事件的绑定,其中包括对UI控件的声明,对Activity之间,Fragment之间参数的声明,对于一些数值进行非空的声明等等。

    (一)UI的绑定以及事件绑定
    (二)简化线程

    在Android中,为了不阻塞主进程,所以所有的耗时操作是不予许在UI线程进行的,不然就会Crash。但是在开发当中却是需要大量的时候耗时操作的,例如对磁盘的读写操作,进行网络的请求,对于图片的操作等等,同时往往在进行这样的耗时操作的时候又会伴随的必须、只能在UI线程进行的操作。例如取回网络数据,进行解析之后要更新UI界面。这样来回的切换会造成开发的不变以及大量的代码冗余。尽管java已经有成熟的thread以及比较方便的AnsyncTask。但是所有的都不如一个注释方便。

    (三)对于网络请求的操作

    在Annotation中,我们可以把所有网络有关的操作集中成一个工具类:
    get、post、put、delete等操作。

    @EActivity
    值得注意的是,Annotation的工作方式是经过编译之后,生成一个类名相同而且带有_的文件,例如LoginActivity会变成LoginActivity_,因此在Manifest中声明Activity的时候是必须带有_的,不然会报错。

    -------------------------带layout-------------------------
    @EActivity(R.layout.main)
    public class MyActivity extends Activity {
    
    }
    
    
    -------------------------不带layout-------------------------
    @EActivity
    public class MyActivity extends Activity {
    
      @Bean
      MyOtherClass myOtherClass;
    
    }
    

    @fragment

    @EFragment(R.layout.my_fragment_layout)
    public class MyFragment extends Fragment {
    }
    
    -------------------------XML注册-------------------------
    <fragment
            android:id="@+id/myFragment"
            android:name="com.company.MyFragment_"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    
    -------------------------创建-------------------------
    MyFragment fragment = new MyFragment_();
    
    
    
    

    @Bean

    -------------------------普通类-------------------------
    @EBean
    public class MyClass {
        //注意:这个类必须仅仅只能有一个构造函数,参数最多有一个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;
    
    }
    
    
    -------------------单例类需要如下声明----------------
    @EBean(scope = Scope.Singleton)
    public class MySingleton {
    //注意:在单例类里面不可以注入view和事件绑定,因为单例的生命周期比Activity和Service的要长,以免发生内存溢出。
    }
    
    
    -------------------------接口-------------------------
    @Bean(MyImplementation.class)
     MyInterface myInterface;
    

    @AfterInject

      @AfterInject
      public void doSomethingAfterInjection() {
        // notificationManager and dependency are set
        //类创建时期做一些操作
      }
    

    @EView

    @EView
    public class CustomButton extends Button {
    
            @App
            MyApplication application;
    
            @StringRes
            String someStringResource;
    
        public CustomButton(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    }
    
    ----------------------------注册------------------------------
    <com.androidannotations.view.CustomButton_
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    ----------------------------创建------------------------------
    CustomButton button = CustomButton_.build(context);
    
    

    @EViewGroup

    @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);
        }
    
    }
    
    -----------------------注册----------------------
    <com.androidannotations.viewgroup.TitleWithSubtitle_
            android:id="@+id/firstTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    

    @EApplication

    @EApplication
    public class MyApplication extends Application {
    
    }
    
    -----------------------Activity中使用----------------------
    @EActivity
    public class MyActivity extends Activity {
    
      @App
      MyApplication application;
    
    }
    
    

    @EService

    @EService
    public class MyService extends Service {
    
    }
    
    -------------------------跳转service--------------------------
    MyService_.intent(getApplication()).start();
    
    
    -------------------------停止service--------------------------
    MyService_.intent(getApplication()).stop();
    

    @EReceiver

    @EReceiver
    public class MyReceiver extends BroadcastReceiver {
    
    }
    

    @Receiver

    
    @EActivity
    public class MyActivity extends Activity {
    
      @Receiver(actions = "org.androidannotations.ACTION_1")
      protected void onAction1() {
        //可以替代声明BroadcastReceiver
      }
    
    }
    

    @EProvider

    @EProvider
    public class MyContentProvider extends ContentProvider {
    
    }
    

    @ViewById

    @EActivity
    public class MyActivity extends Activity {
    
      // Injects R.id.myEditText,变量名称必须和布局的id名称一致
      @ViewById
      EditText myEditText;
    
      @ViewById(R.id.myTextView)
      TextView textView;
    }
    

    @AfterViews

    @EActivity(R.layout.main)
    public class MyActivity extends Activity {
    
        @ViewById
        TextView myTextView;
    
        @AfterViews
        void updateTextWithDate() {
        //一定要在这里进行view的一些设置,不要在oncreate()中设置,因为oncreate()在执行时 view还没有注入
        myTextView.setText("Date: " + new Date());    }[...]
    

    @StringRes

    @EActivity
    public class MyActivity extends Activity {
    
      @StringRes(R.string.hello)
      String myHelloString;//不能设置成私有变量
    
      @StringRes
      String hello;
    
    }
    

    @ColorRes

    @EActivity
    public class MyActivity extends Activity {
    
      @ColorRes(R.color.backgroundColor)
      int someColor;
    
      @ColorRes
      int backgroundColor;
    
    }
    

    @AnimationRes

    @EActivity
    public class MyActivity extends Activity {
    
      @AnimationRes(R.anim.fadein)
      XmlResourceParser xmlResAnim;
    
      @AnimationRes
      Animation fadein;
    
    }
    

    @DimensionRes

    @EActivity
    public class MyActivity extends Activity {
    
      @DimensionRes(R.dimen.fontsize)
      float fontSizeDimension;
    
      @DimensionRes
      float fontsize;
    
    }
    

    @DImensionPixelOffsetRes

    @EActivity
    public class MyActivity extends Activity {
    
      @DimensionPixelOffsetRes(R.string.fontsize)
      int fontSizeDimension;
    
      @DimensionPixelOffsetRes
      int fontsize;
    
    }
    

    @DimensionPixelSizeRes

    @EActivity
    public class MyActivity extends Activity {
    
      @DimensionPixelOffsetRes(R.string.fontsize)
      int fontSizeDimension;
    
      @DimensionPixelOffsetRes
      int fontsize;
    
    }
    

    @DimensionPixelSizeRes

    @EActivity
    public class MyActivity extends Activity {
    
      @DimensionPixelSizeRes(R.string.fontsize)
      int fontSizeDimension;
    
      @DimensionPixelSizeRes
      int fontsize;
    
    }
    

    其他的Res

    @BooleanRes
    @ColorStateListRes
    @DrawableRes
    @IntArrayRes
    @IntegerRes
    @LayoutRes
    @MovieRes
    @TextRes
    @TextArrayRes
    @StringArrayRes
    

    @Extra

    -----------------------方式一---------------------------
    @EActivity
    public class MyActivity extends Activity {
    
      @Extra("myStringExtra")
      String myMessage;
    
      @Extra("myDateExtra")
      Date myDateExtraWithDefaultValue = new Date();
    
    }
    
    -----------------------方式二---------------------------
    @EActivity
    public class MyActivity extends Activity {
    
      // The name of the extra will be "myMessage",名字必须一致
      @Extra
      String myMessage;
    }
    
    -----------------------传值---------------------------
    MyActivity_.intent().myMessage("hello").start() ;
    

    @SystemService

    @EActivity
    public class MyActivity extends Activity {//
      @SystemService
      NotificationManager notificationManager;
    
    }
    

    @HtmlRes

    @EActivity
    public class MyActivity extends Activity {
    
      // Injects R.string.hello_html
      @HtmlRes(R.string.hello_html)
      Spanned myHelloString;
    
      // Also injects R.string.hello_html
      @HtmlRes
      CharSequence helloHtml;
    
    }
    

    FromHtml

    @EActivity
    public class MyActivity extends Activity {//必须用在TextView
    
      @ViewById(R.id.my_text_view)
      @FromHtml(R.string.hello_html)
      TextView textView;
    
      // Injects R.string.hello_html into the R.id.hello_html view
      @ViewById
      @FromHtml
      TextView helloHtml;
    
    }
    

    @NonConfigurationInstance

    public class MyActivity extends Activity {
      //等同于 Activity.onRetainNonConfigurationInstance()
     //http://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance()) 
      @NonConfigurationInstance Bitmap someBitmap; 
      @NonConfigurationInstance 
      @Bean MyBackgroundTask myBackgroundTask;
    }
    

    @HttpsClient

    @HttpsClient
    HttpClient httpsClient;
    
    -------------------------示例----------------------------
    @EActivity
    public class MyActivity extends Activity {
    
        @HttpsClient(trustStore=R.raw.cacerts, trustStorePwd="changeit",hostnameVerif=true)
        HttpClient httpsClient;
    
        @AfterInject
        @Background
        public void securedRequest() {
            try {
                HttpGet httpget = new HttpGet("https://www.verisign.com/");
                HttpResponse response = httpsClient.execute(httpget);
                doSomethingWithResponse(response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @UiThread
        public void doSomethingWithResponse(HttpResponse resp) {
            LogUtils("HTTP status " + resp.getStatusLine().getStatusCode());
        }
    }
    

    @FragmentArg

    @EFragment
    public class MyFragment extends Fragment {//等同于 Fragment Argument
      @FragmentArg("myStringArgument") 
      String myMessage; 
    
      @FragmentArg 
      String anotherStringArgument; 
    
      @FragmentArg("myDateExtra") 
      Date myDateArgumentWithDefaultValue = new Date();
    }
    
    -------------------------------------------------
    MyFragment myFragment = MyFragment_.builder()
      .myMessage("Hello")
      .anotherStringArgument("World")
      .build();
    

    @Click

    @Click(R.id.myButton)
    void myButtonWasClicked() {
        [...]
    }
    @Click
    void anotherButton() {//如果不指定则函数名和id对应
        [...]
    }
    @Click
    void yetAnotherButton(View clickedView) {
        [...]
    }
    

    其他点击事件

    Item clicks with @ItemClick

    Long item clicks with @ItemLongClick

    Item selection with @ItemSelect

    Clicks with @Click

    Long clicks with @LongClick

    Touches with @Touch

    @EActivity(R.layout.my_list)
    public class MyListActivity extends Activity {
    
        // ...
    
        @ItemClick
        public void myListItemClicked(MyItem clickedItem) {
        //MyItem是adapter的实体类,等同于adapter.getItem(position)
    
        }
    
        @ItemLongClick
        public void myListItemLongClicked(MyItem clickedItem) {
    
        }
    
        @ItemSelect
        public void myListItemSelected(boolean selected, MyItem selectedItem) {
    
        }
    
    }
    
    --------------------------------------------
    @EActivity(R.layout.my_list)
    public class MyListActivity extends Activity {
    
        // ...
    
        @ItemClick
        public void myListItemClicked(int position) {//位置id
    
        }
    
        @ItemLongClick
        public void myListItemLongClicked(int position) {
    
        }
    
        @ItemSelect
        public void myListItemSelected(boolean selected, int position) {
    
        }
    
    }
    

    @SeekBarProgressChange
    //等同于SeekBar.OnSeekBarChangeListener.onProgressChanged(SeekBar, int, boolean)

    @SeekBarProgressChange(R.id.seekBar)
     void onProgressChangeOnSeekBar(SeekBar seekBar, int progress, boolean fromUser) {
        // Something Here
     }
    
     @SeekBarProgressChange(R.id.seekBar)
     void onProgressChangeOnSeekBar(SeekBar seekBar, int progress) {
        // Something Here
     }
    
     @SeekBarProgressChange({R.id.seekBar1, R.id.seekBar2})
     void onProgressChangeOnSeekBar(SeekBar seekBar) {
        // Something Here
     }
    
     @SeekBarProgressChange({R.id.seekBar1, R.id.seekBar2})
     void onProgressChangeOnSeekBar() {
        // Something Here
     }
    

    @SeekBarTouchStart 和 @SeekBarTouchStop
    //接受开始和结束事件的监听

    @TextChange

    @TextChange(R.id.helloTextView)
     void onTextChangesOnHelloTextView(CharSequence text, TextView hello,
     int before, int start, int count) {
        // Something Here
     }
    
     @TextChange
     void helloTextViewTextChanged(TextView hello) {
        // Something Here
     }
    
     @TextChange({R.id.editText, R.id.helloTextView})
     void onTextChangesOnSomeTextViews(TextView tv, CharSequence text) {
        // Something Here
     }
    
     @TextChange(R.id.helloTextView)
     void onTextChangesOnHelloTextView() {
        // Something Here
     }
    

    @BeforeTextChange @AfterTextChange

    @BeforeTextChange(R.id.helloTextView)
     void beforeTextChangedOnHelloTextView(TextView hello, CharSequence text, int start, int count, int after) {
        // Something Here
     }
    
     @BeforeTextChange
     void helloTextViewBeforeTextChanged(TextView hello) {
        // Something Here
     }
    
     @BeforeTextChange({R.id.editText, R.id.helloTextView})
     void beforeTextChangedOnSomeTextViews(TextView tv, CharSequence text) {
        // Something Here
     }
    
     @BeforeTextChange(R.id.helloTextView)
     void beforeTextChangedOnHelloTextView() {
        // Something Here
     }
    

    @OptionsMenu和OptionsItem

    @EActivity
    @OptionsMenu(R.menu.my_menu)
    public class MyActivity extends Activity {
    
        @OptionMenuItem
        MenuItem menuSearch;
    
        @OptionsItem(R.id.menuShare)
            void myMethod() {
              // You can specify the ID in the annotation, or use the naming convention
            }
    
        @OptionsItem
        void homeSelected() {
          // home was selected in the action bar
              // The "Selected" keyword is optional
        }
    
        @OptionsItem
        boolean menuSearch() {
              menuSearch.setVisible(false);
              // menuSearch was selected
              // the return type may be void or boolean (false to allow normal menu processing to proceed, true to consume it here)
              return true;
        }
    
        @OptionsItem({ R.id.menu_search, R.id.menu_delete })
        void multipleMenuItems() {
          // You can specify multiple menu item IDs in @OptionsItem
        }
    
        @OptionsItem
        void menu_add(MenuItem item) {
          // You can add a MenuItem parameter to access it
        }
    }
    
    ---------------------------------------------
    @EActivity
    @OptionsMenu({R.menu.my_menu1, R.menu.my_menu2})
    public class MyActivity extends Activity {
    
    }
    

    @Background

    --------------执行--------------
    void myMethod() {
        someBackgroundWork("hello", 42);
    }
    
    @Background
    void someBackgroundWork(String aParam, long anotherParam) {
        [...]
    }
    
    ----------------取消---------------
    void myMethod() {
        someCancellableBackground("hello", 42);
        [...]
        boolean mayInterruptIfRunning = true;
        BackgroundExecutor.cancelAll("cancellable_task", mayInterruptIfRunning);
    }
    
    @Background(id="cancellable_task")
    void someCancellableBackground(String aParam, long anotherParam) {
        [...]
    }
    
    ---------------非并发执行-------------
    void myMethod() {
        for (int i = 0; i < 10; i++)
            someSequentialBackgroundMethod(i);
    }
    
    @Background(serial = "test")
    void someSequentialBackgroundMethod(int i) {
        SystemClock.sleep(new Random().nextInt(2000)+1000);
        Log.d("AA", "value : " + i);
    }
    
    -------------------延迟------------------
    @Background(delay=2000)
    void doInBackgroundAfterTwoSeconds() {
    }
    

    @UiThread

    @Backgroud
    
    void toDoSomeHeavyWork(){
    
      //进行一些耗时的操作
    
    setView();//需要进行UI操作的时候
    
    }
    
    @UIThread
    
    void setView(){
    
      //进行一些只能在UI主线程上进行的操作
    
    }
    
    
    ---------------UI线程--------------
    void myMethod() {
        doInUiThread("hello", 42);
    }
    
    @UiThread
    void doInUiThread(String aParam, long anotherParam) {
        [...]
    }
    
    ------------------延迟-------------------
    @UiThread(delay=2000)
    void doInUiThreadAfterTwoSeconds() {
    }
    
    -----------------优化UI线程--------------
    @UiThread(propagation = Propagation.REUSE)
    void runInSameThreadIfOnUiThread() {
    }
    
    ----------------------进度值改变--------------------
    @EActivity
    public class MyActivity extends Activity {
    
      @Background
      void doSomeStuffInBackground() {
        publishProgress(0);
        // Do some stuff
        publishProgress(10);
        // Do some stuff
        publishProgress(100);
      }
    
      @UiThread
      void publishProgress(int progress) {
        // Update progress views
      }
    
    }
    

    @OnActivityResult

    @OnActivityResult(REQUEST_CODE)
     void onResult(int resultCode, Intent data) {
     }
    
     @OnActivityResult(REQUEST_CODE)
     void onResult(int resultCode) {
     }
    
     @OnActivityResult(ANOTHER_REQUEST_CODE)
     void onResult(Intent data) {
     }
    
     @OnActivityResult(ANOTHER_REQUEST_CODE)
     void onResult() {
     }
    
    四、关于RetentionPolicy

    ** CLASS:** 编译时注解
    ** RUNTIME:** 运行时注解
    ** SOURCE:** 源码注解

    不同的注解有各自的生命周期,根据你实际使用来确定使用哪种类型的注解。

    五、@Target ( 目标)

    用于指定被修饰的Annotation能用于修饰哪些程序单元,只能修饰Annotation定义。它包含一个名为value的成员变量,取值如下:

    @Target(ElementType.ANNOTATION_TYPE):指定该该策略的Annotation只能修饰Annotation.
    @Target(ElementType.TYPE) //接口、类、枚举、注解
    @Target(ElementType.FIELD) //成员变量(字段、枚举的常量)
    @Target(ElementType.METHOD) //方法
    @Target(ElementType.PARAMETER) //方法参数
    @Target(ElementType.CONSTRUCTOR) //构造函数
    @Target(ElementType.LOCAL_VARIABLE)//局部变量
    @Target(ElementType.PACKAGE) ///修饰包定义
    @Target(ElementType.TYPE_PARAMETER) //java8新增,后面Type Annotation有介绍
    @Target(ElementType.TYPE_USE) ///java8新增,后面Type Annotation有介绍
    @Target(ElementType.FIELD)
    public @interface ActionListenerFor{}

    六、@Documented

    用于指定被修饰的Annotation将被javadoc工具提取成文档。即说明该注解将被包含在javadoc中。

    七、@Inherited

    用于指定被修饰的Annotation具有继承性。即子类可以继承父类中的该注解。---》注解@WW被元注解@Inherited修饰,把@WW添加在类Base上,则Base的所有子类也将默认使用@WW注解。

    相关文章

      网友评论

        本文标题:Android Annotation 注解框架

        本文链接:https://www.haomeiwen.com/subject/cuienttx.html