在使用Java的SSH框架的时候,一直在感叹注解真是方便啊,关于注解的原理,大家可以参考我的另一片文章Java注解详解。最近有时间研究了android注解的使用,今天与大家分享一下。

android中注解的使用用到了GitHub上的开源框架androidannotations,下载地址。这个开源框架应该是目前使用人数最多的android注解框架了,主要是由于它设计的注解标签非常多,能够满足我们日常开发中的大部分需求。androidannotations将许多可以抽取出来的方法都包装成了注解标签供我们使用,一会我会给大家具体演示。

好了,言归正传,我们一起来看看怎么使用这个东东。


第一步

下载androidannotations

下载之后解压文件,我们会看到有两个jar包:


第二步

在eclipse上配置框架:

1.新建一个android项目,把androidannotations-api-3.2.jar拷贝到libs文件夹中,同时在项目中新建一个文件夹,叫做compile-lib,把androidannotations-3.2.jar文件拷贝进去。如图:



2.选中项目,右键单击,选择Properties,在新窗口左边可以看到Java Compiler,选中Java Compiler下的Annotation Processin,然后选中右边的Enable project specific Settings,允许给项目一些特殊设置。如图:



3.展开Annotation Processin,选中Factory Path,然后点击右边的Enable project specific Settings,最后点击Add JARs,添加jar包。如图:

4.选中我们刚刚新建文件夹中的jar包,一路点击OK即可,如图

好了,至此我们的开发环境上的配置就完成了


第三步

测试配置是否成功

在一个Activity上输入@E,看看提示什么:

如果你看到了@EActivity,那么恭喜你,配置成功,如果没有看到,请检查以上步骤。

如图:


第四步

配置好了,接下来我们就要看看怎么使用androidannotations了。

1.Activity注解的使用

修改清单文件中的activity配置,我们要在MainActivity后面添加一个_:

  1. <activity
  2. android:name=".MainActivity_"
  3. android:label="@string/app_name" >
  4. <intent-filter>
  5. <action android:name="android.intent.action.MAIN" />
  6. <category android:name="android.intent.category.LAUNCHER" />
  7. </intent-filter>
  8. </activity>

至于为什么要把MainActivity改为MainActivity_,我在后面会给大家解释。然后在MainActivity上添加注解:

  1. @EActivity(R.layout.activity_main)
  2. public class MainActivity extends Activity {

删除掉onCreate()方法中的setContentView(R.layout.activity_main);,如图:

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. }

为了方便起见,我们先在主布局文件中添加一些控件:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:paddingBottom="@dimen/activity_vertical_margin"
  6. android:paddingLeft="@dimen/activity_horizontal_margin"
  7. android:paddingRight="@dimen/activity_horizontal_margin"
  8. android:paddingTop="@dimen/activity_vertical_margin"
  9. android:orientation="vertical"
  10. tools:context="com.example.androidannotations.MainActivity" >
  11. <TextView
  12. android:id="@+id/textView1"
  13. android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"
  15. android:text="@string/hello_world" />
  16. <Button
  17. android:id="@+id/button1"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. android:text="Button1" />
  21. <Button
  22. android:id="@+id/button2"
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:text="Button2" />
  26. <Button
  27. android:id="@+id/button3"
  28. android:layout_width="wrap_content"
  29. android:layout_height="wrap_content"
  30. android:text="Button3" />
  31. <Button
  32. android:id="@+id/button4"
  33. android:layout_width="wrap_content"
  34. android:layout_height="wrap_content"
  35. android:text="Button4" />
  36. <Button
  37. android:id="@+id/button5"
  38. android:layout_width="wrap_content"
  39. android:layout_height="wrap_content"
  40. android:text="Go TO Next Activity" />
  41. <Button
  42. android:id="@+id/button6"
  43. android:layout_width="wrap_content"
  44. android:layout_height="wrap_content"
  45. android:text="多线程事件" />
  46. <TextView
  47. android:id="@+id/textView2"
  48. android:layout_width="wrap_content"
  49. android:layout_height="wrap_content"
  50. android:text="TextView" />
  51. <TextView
  52. android:id="@+id/textView3"
  53. android:layout_width="wrap_content"
  54. android:layout_height="wrap_content"
  55. android:text="TextView" />
  56. <TextView
  57. android:id="@+id/textView4"
  58. android:layout_width="wrap_content"
  59. android:layout_height="wrap_content"
  60. android:text="TextView" />
  61. </LinearLayout>

这个时候我们运行看看,在没有给Activity设置布局的情况下系统有没有报错:

没有崩溃,所有内容正常显示,由此可见@EActivity(R.layout.activity_main)代替了setContentView(R.layout.activity_main);,这个使用起来更加方便。

再介绍一个和Activity有关的注解,我们在Activity使用过程中,经常需要重新自定义标题栏,从而需要隐藏系统默认的标题栏,那么这个该怎么实现呢:

  1. @WindowFeature({ Window.FEATURE_NO_TITLE , Window.FEATURE_INDETERMINATE_PROGRESS})
  2. @EActivity(R.layout.activity_main)
  3. public class MainActivity extends Activity {

效果图:



标题栏成功隐藏,比我们其他的隐藏标题的方式都方便吧。

2.实例化控件注解

实例化控件注解是androidannotations中又一个非常好用的注解,也解决了我们开发过程中最枯燥的一项工作,正常情况下,我们实例化一个控件要使用findViewById,拿到控件后再强转为我们需要的类型,代码量大,而且枯燥,那么看看androidannotations带给我们什么惊喜呢?

我们的主布局文件上一共有四个TextView,我使用以下三种方式来进行实例化:

  1. @ViewById(R.id.textView1)
  2. TextView tv1;
  3. @ViewById
  4. TextView textView2;
  5. @ViewsById({R.id.textView3,R.id.textView4})
  6. List<TextView> list;

第一种:@ViewById(R.id.textView1)这是非常标准的写法。声明一个控件之后,然后使用@ViewById注解,在注解中说明这个控件的id,这样相当于代替了这样一行代码:

  1. TextView tv1 = (TextView) this.findViewById(R.id.textView1);

第二种:我没有指明这个注解标签要用的id,那么它是怎么实例化的呢?在没有指明的情况下,androidannotations会使用控件名作为id,我的第二个控件名叫做textView2,与xml中的布局id是一样的,因此可以不用在注解中指定id.

第三种:如果要声明多个控件,可以把这些控件放入一个List集合中,然后在注解中指明多个id即可。

控件实例化之后,紧跟着就可以给控件赋值了:

  1. @AfterViews
  2. public void initTextView(){
  3. tv1.setText("hello world!");
  4. textView2.setText("hello android annotations!");
  5. for(TextView tv:list){
  6. tv.setText("hello lenve!");
  7. }
  8. }

这个方法会在实例完控件后执行。

3.事件注解

我们开发中用的较多的事件androidannotations几乎都给我们提供了注解:


  1. @TextChange
  2. @AfterTextChange
  3. @BeforeTextChange
  4. @EditorAction
  5. @FocusChange
  6. @CheckedChange
  7. @Touch
  8. @Click
  9. @LongClick
  10. @ItemClick
  11. @ItemLongClick
  12. @ItemSelect
  13. @OptionsItem
  14. @SeekBarProgressChange
  15. @SeekBarTouchStart
  16. @SeekBarTouchStop

我这里挑个简单的,也是最常用的说一下,算是抛砖引玉了:

  1. @Click({R.id.button1,R.id.button2,R.id.button3})
  2. public void btn_click(View v){
  3. switch (v.getId()) {
  4. case R.id.button1:
  5. Toast.makeText(this,"btn1", Toast.LENGTH_LONG).show();
  6. break;
  7. case R.id.button2:
  8. Toast.makeText(this,"btn2", Toast.LENGTH_LONG).show();
  9. break;
  10. case R.id.button3:
  11. Toast.makeText(this,"btn3", Toast.LENGTH_LONG).show();
  12. break;
  13. }
  14. }
  15. @Click(R.id.button4)
  16. public void btn4_click(){
  17. Toast.makeText(this,"btn4", Toast.LENGTH_LONG).show();
  18. }

在方法之上添加@Click注解,在注解中指明这是哪个控件的点击事件,如果是多个事件的点击事件,就注明多个id,在方法中使用v.getId()方法来进行区分。如果只给一个控件设置点击事件,那看button4的例子。

事件的注解其实是比较简单的,我就不多说了,大家有兴趣可以查看官方文档

4.线程注解

这大概是最让我激动的一个注解了。这里主要给大家介绍两个注解:

  1. @Background
  2. @UiThread

毫无疑问,@Background是让方法在子线程中运行,而@UiThreaad则是让方法在UI线程中运行。

我们来实现一个简单的效果,点击一个按钮之后,让一个TextView自动更新值。

  1. @Background
  2. public void doInBackground(){
  3. try {
  4. for (int i = 0; i < 100; i++) {
  5. tvShowNumber(i);
  6. Thread.sleep(1000);
  7. }
  8. } catch (InterruptedException e) {
  9. e.printStackTrace();
  10. }
  11. }
  12. @UiThread
  13. public void tvShowNumber(int i) {
  14. list.get(1).setText(i+"");
  15. }

首先,在doInBackground方法中,每隔1秒执行一次tvShowNumber(i);方法,这个方法如果在主线程中运行会导致ANR异常,所以必须在子线程中运行,但是android中有不允许在子线程中更新UI线程,所以我们要在tvShowNumber方法上添加@UiThread标签,表明该方法是在UI线程中运行的。

看看效果图:

这里彻底抛弃了烦人的Message、Handler(此处该有掌声)。

5.Activity之间传值注解

Activity之间的跳转经常需要数据的传递,在新的Activity中需要通过Bundle来获得这些数据,还要判断是否为空,非常麻烦,看看androidannotations是怎么解决这个问题的:

新建一个SecondActivity,注意要修改清单文件,在文件后面加上_:

  1. <activity
  2. android:name=".SecondActivity_"
  3. android:label="@string/title_activity_second" >
  4. </activity>

SecondActivity接收MainActivity传来的两个参数,一个是name,一个是address,我们先来看看MainActivity中的代码:

  1. @Click(R.id.button5)
  2. public void go2NextActivity(){
  3. //这里要注意第二个Activity的写法
  4. Intent intent = new Intent(this,SecondActivity_.class);
  5. intent.putExtra("name", "张三");
  6. intent.putExtra("address", "xi'an");
  7. startActivity(intent);
  8. }

在SecondActivity中获得MainActivity中传来的值:

  1. @Extra("name")
  2. String username;
  3. @Extra
  4. String address;

和上文一样,如果参数名相同,则不用在注解中说明参数名称,否则要指明。这样就自动拿到MainActivity中传来的值了。如果MainActivity中传来的值为空,也不会报错,系统会自动处理异常情况。

6.资源文件注解

资源文件的使用我们也可以使用注解,比如,在strings.xml中添加一个字符串:

  1. <string name="welcome">hello China,Hello xi\'an and guangzhou</string>

在程序中我们要引用这个值:

  1. @StringRes(R.string.welcome)
  2. String welcome;

这样welcome就自动获得了这里的值。注意@StringRes导入的包是import org.androidannotations.annotations.res.StringRes;,不是android自带的包,别上当了。

效果图:

7关于加_的原因

最后再解决一个问题,就是什么要在清单文件中加_,要回答这个问题请大家先选中项目,右键单击,取消apt_generated前面的一个点。



取消之后,我们的项目里多了一个文件夹:

这里的文件夹中的Activity就是我们刚才新建的Activity,只不过都多了一个下划线,我们打开这些Activity看看:

我们通过注解写的布局文件,它又在这里给我们生成了,所以说,我们最终编译时用的是这里的文件,这也是为什么清单文件中要加下划线了。


注意事项

最后强调一个注意事项,凡是使用注解的代码,一定不要用private修饰最多可以用protected修饰,因为androidannotations在使用注解生成真正的源码时,如果我们的东东被private修饰了,它就没法调用这些东西了,所以最多只能用protected修饰。


关于androidannotations的更多用法大家可以参考官方文档


好了,关于Androidannotations的使用就给大家介绍到这里,有什么问题请留言。本项目源码下载


版权声明:本文为博主原创文章,未经博主允许不得转载。若有错误地方,还望批评指正,不胜感激。

android注解使用详解(图文)的更多相关文章

  1. 【转】Android Canvas绘图详解(图文)

    转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...

  2. Android之canvas详解

    首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, y ...

  3. Java注解(Annotation)详解

    转: Java注解(Annotation)详解 幻海流心 2018.05.23 15:20 字数 1775 阅读 380评论 0喜欢 1 Java注解(Annotation)详解 1.Annotati ...

  4. android:ToolBar详解

    android:ToolBar详解(手把手教程) 泡在网上的日子 发表于 2014-11-18 12:49 第 124857 次阅读 ToolBar 42 来源 http://blog.mosil.b ...

  5. Android 核心分析 之八Android 启动过程详解

    Android 启动过程详解 Android从Linux系统启动有4个步骤: (1) init进程启动 (2) Native服务启动 (3) System Server,Android服务启动 (4) ...

  6. Android GLSurfaceView用法详解(二)

    输入如何处理       若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...

  7. Android编译过程详解(一)

    Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...

  8. android屏幕适配详解

    android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...

  9. Android.mk文件详解(转)

    源:Android.mk文件详解 从对Makefile一无所知开始,折腾了一个多星期,终于对Android.mk有了一个全面些的了解.了解了标准的Makefile后,发现Android.mk其实是把真 ...

随机推荐

  1. [收藏转贴]struct探索·extern "C"含义探索 ·C++与C的混合编程·C 语言高效编程的几招

    一.C/C++语言 struct深层探索 1.自然对界 struct是一种复合数据类型,其构成元素既可以是基本数据类型(如 int.long.float等)的变量,也可以是一些复合数据类型(如 arr ...

  2. springboot + devtools(热部署)

    技术介绍 devtools:是boot的一个热部署工具,当我们修改了classpath下的文件(包括类文件.属性文件.页面等)时,会重新启动应用(由于其采用的双类加载器机制,这个启动会非常快,如果发现 ...

  3. Adobe Flash Builder 4.7下载地址及破解补丁(32位&64位)

    Adobe FlashBuilder 4.7是开发flex的利器,能显著提高flex的开发效率.最新版的是4.7,去官网上下载时每次都要登录才能下载,特麻烦,这次下载时就把相关的下载地址给记录了下来, ...

  4. 【CF】3B Lorry

    这道题目网上有几个题解,均有问题.其实就是简单的贪心+排序,没必要做的那么复杂.一旦tot+curv > v时,显然curv==2, 有三种可能:(1)取出最小的curv==1的pp,装入当前的 ...

  5. 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    一张图看懂开源许可协议,开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区别 首先借用有心人士的一张相当直观清晰的图来划分各种协议:开源许可证GPL.BSD.MIT.Mozi ...

  6. Electrification Plan(最小生成树)

    http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=50#problem/D 最小生成树模板,注意的是这里有k个发电站,它们不再需要连 ...

  7. NET Framework GAC目录构造

    转:http://www.yl1001.com/userzone.htm?doaction=article&art_id=5851381388387201 我们一般都知道,.NET Frame ...

  8. 算法 python实现(二) 冒泡排序

    首先说一下 冒泡排序 是怎么做的: 总体的想法是,把小的轻的浮上前面去,把大的重的沉到后面去. 这样设置两个指针,i j, 1. i标识每一趟循环.这一趟的目的是把后面那些未排序的数列中最小的浮上前面 ...

  9. 【单页应用】view与model相关梳理(转载)

    [单页应用]view与model相关梳理 前情回顾 根据之前的学习,我们形成了一个view与一个messageCenterview这块来说又内建了一套mvc的东西,我们这里来理一下首先View一层由三 ...

  10. 基于Noootes/Dooomino的文档工作流系统(转)

    (流程样例应用程序终于整理上传好可供下载了http://download.csdn.net/download/starrow/8422299) 上文分析了我们的流程配置使用三类对象,分别对应三类文档: ...