zoukankan      html  css  js  c++  java
  • Android Annotations 注解例子

      1、AndroidAnnotations官网: http://androidannotations.org/ (也许你需要FQ)

      2、eclipse中使用androidannotations的配置方法说明:https://github.com/excilys/androidannotations/wiki/Eclipse-Project-Configuration

      3、Android Studio中配置AndroidAnnotations:(这个是我这篇博文中要涉及到的!)

    一、Android Studio配置androidannotations环境。

    1、首先你建立一个module之后,在对应的app中会有一个名为build.gradle的文件(该module有效),而在整个项目外面也会有一个名为build.gradle的文件(全局有效)【这个工具中的application的目录下(相当于Eclipse下的workspace)是可以有多个module的(相当于Eclipse下的project)】

    2、我们配置的时候大概要分为下面两步

    在局部build.gradle中(加入 红色字体部分 ):

    apply plugin: 'com.android.application'

    apply plugin: 'android-apt'

    android {

        compileSdkVersion 19

        buildToolsVersion "20.0.0"

        defaultConfig {

            applicationId "com.tongbu.mytest"

            minSdkVersion 8

            targetSdkVersion 19

            versionCode 1

            versionName "1.0"

        }

        buildTypes {

            release {

                runProguard false

                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            }

        }

    }

    dependencies {

        compile fileTree(dir: 'libs', include: ['*.jar'])

        compile 'com.android.support:appcompat-v7:19.+'

       

    apt "org.androidannotations:androidannotations:$AAVersion"

    }

    apt {

        arguments {

            androidManifestFile variant.processResources.manifestFile

            resourcePackageName 'com.tongbu.mytest'

        }

    }

    在全局build.gradle中(加入 红色字体部分 ):

    buildscript {

        repositories {

            jcenter()

        }

        dependencies {

            classpath 'com.android.tools.build:gradle:0.12.+'

            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.3'

        }

    }

    allprojects {

        repositories {

            jcenter()

        }

    }

    如果以上的都顺利完成了,那么恭喜你已经快配置完了,还需要把AndroidManifest.xml中的Activity的名字后面加上 _(下划线),因为这个框架解析编译的时候,比如类MainActivity会被解析成MainActivity_.class,所以在清单文件中我们要在Activity的名字后面加一个下划线,或者androidannotation会报错!

    但并不会这么顺利,在你补充完下划线之后,你会发现会提示你找不到MainActivity_这个东东

    那么怎么办呢??我们说了它是在编译的时候整出来的,那我们只要按一下编译的按钮即可生成了!!

    这样子androidannotation在android studio上的环境就配置好了

    Android 最火快速开发框架AndroidAnnotations简介文章中的简单介绍,本篇注重讲解AndroidAnnotations中注解方法的使用。

    @EActivity

     示例:

    @EActivity(R.layout.main)
    public class MyActivity extends Activity {
    
    }

    @fragment

    示例:

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

    注册:

    <fragment
            android:id="@+id/myFragment"
            android:name="com.company.MyFragment_"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

    创建:

    MyFragment fragment = new MyFragment_();

    普通类:

    @EBean
    public class MyClass {
    
    }

    注意:这个类必须仅仅只能有一个构造函数,参数最多有一个context。

    Activity中使用:

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

    也可以用来声明接口:

    @Bean(MyImplementation.class)
        MyInterface myInterface;

    在普通类中还可以注入根环境:

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

    如果想在类创建时期做一些操作可以:

    @AfterInject
      public void doSomethingAfterInjection() {
        // notificationManager and dependency are set
      }

    单例类需要如下声明:

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

    注意:在单例类里面不可以注入view和事件绑定,因为单例的生命周期比Activity和Service的要长,以免发生内存溢出。

    @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
    可以替代声明BroadcastReceiver
    @EActivity
    public class MyActivity extends Activity {
    
      @Receiver(actions = "org.androidannotations.ACTION_1")
      protected void onAction1() {
    
      }
    
    }
     
    @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;

    @ViewByIds({R.id.id1,R.id.id2})
    List<TextView> list; }




    @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 {
    
      @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()
    
      @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) {
            Toast.makeText(this, "HTTP status " + resp.getStatusLine().getStatusCode(), Toast.LENGTH_LONG).show();
        }
    }
     
    @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) {
        [...]
    }
    其他点击事件:
    • Clicks with @Click
    • Long clicks with @LongClick
    • Touches with @Touch

    AdapterViewEvents 

    • Item clicks with @ItemClick
    • Long item clicks with @ItemLongClick
    • Item selection with @ItemSelect
    有两种方式调用:
    1.
    @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) {
    
        }
    
    }
    2.
    @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 and @SeekBarTouchStop
     
    @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
    @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
     }
     
    @AfterTextChange
    @AfterTextChange(R.id.helloTextView)
     void afterTextChangedOnHelloTextView(Editable text, TextView hello) {
        // Something Here
     }
    
     @AfterTextChange
     void helloTextViewAfterTextChanged(TextView hello) {
        // Something Here
     }
    
     @AfterTextChange({R.id.editText, R.id.helloTextView})
     void afterTextChangedOnSomeTextViews(TextView tv, Editable text) {
        // Something Here
     }
    
     @AfterTextChange(R.id.helloTextView)
     void afterTextChangedOnHelloTextView() {
        // 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
    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() {
     }
    以上的注释用法基本包含了平常程序中的事件绑定,用AndroidAnnotations框架可以专注于做逻辑开发,最主要是简化代码编写,容易维护。
    如有问题可以参考官方文档https://github.com/excilys/androidannotations/wiki/Cookbook
     

    Annotation 解析

    1 运行时 Annotation 解析

    (1) 运行时 Annotation 指 @Retention 为 RUNTIME 的 Annotation,可手动调用下面常用 API 解析

    method.getAnnotation(AnnotationName.class);
    method.getAnnotations();
    method.isAnnotationPresent(AnnotationName.class);

    其他 @Target 如 Field,Class 方法类似
    getAnnotation(AnnotationName.class) 表示得到该 Target 某个 Annotation 的信息,因为一个 Target 可以被多个 Annotation 修饰
    getAnnotations() 则表示得到该 Target 所有 Annotation
    isAnnotationPresent(AnnotationName.class) 表示该 Target 是否被某个 Annotation 修饰
    (2) 解析示例如下:

    public static void main(String[] args) {
        try {
            Class cls = Class.forName("cn.trinea.java.test.annotation.App");
            for (Method method : cls.getMethods()) {
                MethodInfo methodInfo = method.getAnnotation(
    MethodInfo.class);
                if (methodInfo != null) {
                    System.out.println("method name:" + method.getName());
                    System.out.println("method author:" + methodInfo.author());
                    System.out.println("method version:" + methodInfo.version());
                    System.out.println("method date:" + methodInfo.date());
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    以之前自定义的 MethodInfo 为例,利用 Target(这里是 Method)getAnnotation 函数得到 Annotation 信息,然后就可以调用 Annotation 的方法得到响应属性值

    2 编译时 Annotation 解析

    (1) 编译时 Annotation 指 @Retention 为 CLASS 的 Annotation,甴 apt(Annotation Processing Tool) 解析自动解析。需要做的
    a. 自定义类集成自 AbstractProcessor
    b. 重写其中的 process 函数
    这块很多同学不理解,实际是 apt(Annotation Processing Tool) 在编译时自动查找所有继承自 AbstractProcessor 的类,然后调用他们的 process 方法去处理
    (2) 假设之前自定义的 MethodInfo 的 @Retention 为 CLASS,解析示例如下:

    @SupportedAnnotationTypes({ "cn.trinea.java.test.annotation.MethodInfo" })
    public class MethodInfoProcessor extends AbstractProcessor {
     
        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
            HashMap<String, String> map = new HashMap<String, String>();
            for (TypeElement te : annotations) {
                for (Element element : env.getElementsAnnotatedWith(te)) {
                    MethodInfo methodInfo = element.getAnnotation(MethodInfo.class);
                    map.put(element.getEnclosingElement().toString(), methodInfo.author());
                }
            }
            return false;
        }
    } 

    SupportedAnnotationTypes 表示这个 Processor 要处理的 Annotation 名字。
    process 函数中参数 annotations 表示待处理的 Annotations,参数 env 表示当前或是之前的运行环境
    process 函数返回值表示这组 annotations 是否被这个 Processor 接受,如果接受后续子的 rocessor 不会再对这个 Annotations 进行处理

     
  • 相关阅读:
    程序打印的日志哪里去了?结合slf4j来谈谈面向接口编程的重要性
    vue项目用npm安装sass包遇到的问题及解决办法
    nginx反向代理配置及常见指令
    你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程
    jeecg逆向工程代码的生成及常见问题
    java注解
    终于有了,史上最强大的数据脱敏处理算法
    SpringBoot项目下的JUnit测试
    递归方法
    练习题
  • 原文地址:https://www.cnblogs.com/hero4china/p/4625793.html
Copyright © 2011-2022 走看看