本文首发知识星球《Hi Android》
注解不是必须的,但是能极大的帮助我们节约时间和提高开发效率,写此篇文章的初衷,是我课程中的同学想要了解一下这个框架,遂写下此篇文章,其实我们如果想了解Annotations这个框架的话,他的官方示例写得还是比较详细的:
http://androidannotations.org/
https://github.com/androidannotations/androidannotations/wiki
如果你学习我的视频课程,哪怕课程之外的知识点,如果有时间,我也会帮助你提升的,授人予鱼不如授人予渔,我时刻都在培养同学的思维逻辑,只要哪天开窍了,一切都变得简单明了了。
推荐我的慕课网Android实战课程,助你暴力提升Android技术。
https://coding.imooc.com/class/390.html
相对于其他的注解框架,如XUtils、ButterKnife、Dragger等,Annotations的优势在于没有使用到反射,不影响性能,所以如果论性能,Annotations应该是最好的。
不过据说Google官方推出注解框架之后,Annotations的作者就不在更新了。
不过不得不说Annotations的配置要麻烦许多,所以我建议如果不是必须的话,这个还是少用一些,不然重构代码比较麻烦,当然,我现在说这些,对于没有用过Annotations的同学来讲,可能还不太理解,跟着我一起来看下吧。
一.配置Annotations
首先我们来配置一下所需的Gradle,配置Gradle分为两步,第一步是添加依赖
可以看到我定义了一个变量AAVersion来定义版本,第二步则是添加Java编译的配置:
我们在defaultConfig节点中配置如上代码是因为Annotations的编译不像其他框架一样反射,而是通过生成一份子类代码来帮助运行,所以找不到清单文件,我们自己配置下即可。
当然,这个时候还是无法运行的,上面说到Annotations的编译是生成一份子类,所以我们的清单文件也需要修改,在每一个声明的类中加上下划线,如下代码:
做完这些,我们的配置才OK,那么接下来就看下我们怎么使用吧。
二.增强的组件
Annotations对Android中一些重量级的组件都做了增加,我们来看下
1.Activity
首先是如何声明一个Activity的View,传统的写法是setContentView,但是有了Annotations之后,我们可以使用@EActivity这个标签
1@EActivity(R.layout.activity_main)
2public class MainActivity extends AppCompatActivity {
3 //Anything
4}
2.Application
关于Appliation,是必须要使用@EApplication这个标签的
1@EApplication
2public class BaseApp extends Application {
3 //Anything
4}
然后则是在清单文件中注册了,记得加上下划线哦
如果想要使用的话,需要使用@App标签
1@App
2BaseApp mApp;
具体的可以查阅Github wiki
3.Bean
关于实体类,我们可以使用@EBean
1@EBean
2public class JavaBean {
3 //Anything
4}
如果想要使用的话,需要使用@Bean标签
1@Bean
2JavaBean mBean;
具体的可以查阅Github wiki
4.Fragment
关于Fragment就有意思了,首先我们需要使用@EFragment来注解,这个是没问题的,和@EActivity的用法是一样的
1@EFragment(R.layout.fragment_main)
2public class MainFragment extends Fragment {
3 //Anything
4}
这样我们就不需要再调用onCreateView了,当然如果你想使用到onCreateView中的Bundle那么你直接return null 即可,说完注解,我们再来说一下使用,使用是需要下划线的,比如我们在xml中则是如下:
如果是在代码中,则可以使用下面两种任选其一:
1MainFragment mFragment = new MainFragment_();
2//or
3MainFragment mFragment = MainFragment_.builder().build();
5.Provider
内容提供者倒是没什么太大的区别,使用@EProvider注解即可。
6.BrocastReceiver
广播的话分为动态广播和静态广播,动态注册最为简单
1@Receiver(actions = TEST_ACTION)
2protected void test() {
3 //收到广播
4}
我们可以看到只需要通过@Receiver注解标记需要接收的actions即可,而静态广播如下
1@EReceiver
2public class JavaReceiver extends BroadcastReceiver {
3
4 //可以接收Context,Intent 两个参数
5 @ReceiverAction(actions = MainActivity.TEST_ACTION)
6 void test() {
7 //收到广播
8 }
9
10 @Override
11 public void onReceive(Context context, Intent intent) {
12 //什么都不用做
13 }
14}
这里我们也是一样的,我定义了一个test,并且你也可以自己传递上下文或者intent
7.Service
服务的话有两个,一个IntentService和一个Service,我们先来看下IntentService
1@EIntentService
2public class MainIntentService extends IntentService {
3
4 public MainIntentService() {
5 super("MainIntentService");
6 }
7
8 @ServiceAction
9 void myAction(String param) {
10 //接收参数
11 }
12
13
14 @Override
15 protected void onHandleIntent(Intent intent) {
16 //什么都不做
17 }
18}
代码很简单,我们使用@EIntentService注解来标记,使用@ServiceAction注解来接收传递的参数,再来看下我们常见的Service,其实只是使用了@EService注解,我们具体看下他的启动和停止的方法吧。
1//启动服务
2MainService_.intent(this).start();
3//停止服务
4MainService_.intent(this).stop();
8.View
View的情况实际上也是两种,一种是View,一种是ViewGroup,如果是View的话只需要@EView注解即可
当然,使用的方式也分两种,xml或者代码,先看xml
1<com.liuguilin.androidannotations.view.MyTextView_
2 android:text="MyTextView"
3 android:layout_width="wrap_content"
4 android:layout_height="wrap_content"/>
xml包括清单文件中一定要注意下划线,在代码中可以这样
1MyTextView mTextView = MyTextView_.build(this);
如果是ViewGroup的话使用@ViewGroup(R.layout.xxx)
具体的可以查阅Github wiki
三.View注入
关于注入的注解关键字,其实上面已经有讲到一些了,比如@App @Bean 等都是,我们继续来看其他的基本操作
1.ViewById / ViewsById
这两个都是负责初始化的,相信大家一眼就知道什么意思,替代我们的findViewById
1@ViewById(R.id.mTextView)
2TextView mTextView;
3
4@ViewsById({R.id.mTextView, R.id.mYourTextView})
5List<TextView> mTextViews;
2.Extra
扩展属性,常用于Intent的扩展,说白了就是intent的传值,所以我们可以这样使用,这里我的案例是MainActivity跳转FirstActivity,所以我们的FirstActivity可以这样去写:
1@EActivity(R.layout.activity_first)
2public class FirstActivity extends AppCompatActivity {
3
4 @ViewById(R.id.tvFirst)
5 TextView tvFirst;
6
7 @Extra("Name")
8 String mName;
9
10 @AfterViews
11 void initView() {
12 tvFirst.setText(mName);
13 }
14}
可以看到代码还是很明朗的,我初始化了一个文本控件然后接受外部传递的mName设置给文本,那么外部是如何调用的?
1FirstActivity_.intent(this).mName("刘桂林").start();
一行代码即可。
3.AfterViews
我们如果使用ViewById初始化后,在onCreate使用这个对象你会发现是无法使用的,事实上这个时候还没有初始化,AfterViews就是用来告知我们试图已经初始化完成,我们标准的写法是这样的:
1@EActivity(R.layout.activity_main)
2public class MainActivity extends AppCompatActivity {
3
4 @ViewById(R.id.mTextView)
5 TextView mTextView;
6
7 @AfterViews
8 void init(){
9 mTextView.setText("Hello");
10 }
11}
4.FragmentArg
顾名思义,这个是在Fragment中使用的,并且看名字就知道是什么意思了,首先是@FragmentArg,这个注解和@Extra是一样的,用来传递参数
1MainFragment mFragment = MainFragment_
2 .builder()
3 .fragmentArg("Hello")
4 .build();
至于 FragmentById / FragmentByTag 这些不常用的可以自行查阅wiki
5.FromHtml
假设你的strings.xml中有一个html的参数,那么常见的做法是使用Html类去转换成String再赋值给TextView,而使用@FromHtml则无需这么复杂,我们来看下
1<string name="hello_html"><![CDATA[Hello <b>World</b>!]]></string>
这是一段html,我们来加载
1@ViewById(R.id.mTextView)
2@FromHtml(R.string.hello_html)
3TextView mTextView;
这样即可。
6.NonConfigurationInstance
这也是个相对冷门的注解了,当我们的Config配置发生更改,比如切换语言的时候,我们的对象会销毁重建,但是使用此注解可以保存实例
7.SystemService
我们如果需要getSystemService初始化的系统服务都可以使用此注解免去这一个步骤。
四.事件绑定
1.Text 变化
如果我们要监听EditText的输入文本改变,则需要实现他的
TextWatcher.onTextChanged接口,但是注解框架为我们提供了诸多方便的接口,如:
TextChange
BeforeTextChange
AfterTextChange
看如下代码:
1@AfterTextChange(R.id.mEditText)
2void afterTextChanged(Editable text) {
3 //开始改变
4}
5
6@TextChange(R.id.mEditText)
7void onTextChanges(CharSequence text, int before, int start, int count) {
8 //正在改变
9}
10
11@BeforeTextChange(R.id.mEditText)
12void beforeTextChanged(CharSequence text, int start, int count, int after) {
13 //结束改变
14}
其中参数除了text其他的都是可选项
2.状态 变化
状态变化主要取决于焦点以及编辑状态,还有选中,我们可以使用 @FocusChange @EditorAction @CheckedChange
3.事件 监听
事件监听就很多了,比如我们的点击事件,触摸事件,长按事件等
1@Click(R.id.mClick)
2void BttonClick() {
3 //点击事件
4}
5
6@LongClick(R.id.mClick)
7void BttonLongClick() {
8 //长按事件
9}
10
11@Touch(R.id.mClick)
12boolean BttonTouchClick(MotionEvent event) {
13 //触摸事件
14 return false;
15}
当然,我们还有Adapter中的事件监听,如 @ItemClick @ItemLongClick @ItemSelect
还有我们的menu其实也是可以这样设置点击的,我们来看下如下代码
1@OptionsMenu(R.menu.main)
2@EActivity(R.layout.activity_main)
3public class MainActivity extends AppCompatActivity {
4
5 @OptionsItem(R.id.menu_help)
6 void Help() {
7 //Anything
8 }
9
10}
这样即可实现menu与menu的点击事件
4.SeekBar 监听
以往我们监听SeekBar是需要设置监听的,现在不用啦。
1@SeekBarTouchStart(R.id.mSeekBar)
2void SeekBarTouchStart(SeekBar seekBar) {
3 //触摸开始
4}
5
6@SeekBarProgressChange(R.id.mSeekBar)
7void onProgressChangeOnSeekBar(SeekBar seekBar, int progress, boolean fromUser) {
8 //触摸变化
9}
10
11@SeekBarTouchStop(R.id.mSeekBar)
12void SeekBarTouchStop(SeekBar seekBar) {
13 //触摸结束
14}
5.按键 事件
按键共有四个
KeyDown 按下
KeyUp 抬起
KeyLongPress 长按
KeyMultiple 多按
6.ViewPager 监听
ViewPager监听以往是需要addPageListener的,现在提供了三个注解
PageScrollStateChanged
PageScrolled
PageSelected
五.线程
1.后台线程
我们如果想要在子线程中运行,以往都是new Thread().start的,现在只需要@Background
即可,它表示在主线程以外的线程执行
2.主线程
主线程也就是ui线程,我们使用@UiThread注解,代替 runUIThread方法
六.混合
其他还有很多,我们来看下
InstanceState 保存状态
WindowFeature 窗口功能
Fullscreen 全屏
CustomTitle 自定义标题
InjectMenu 注入菜单
OptionsMenu 菜单
OptionsMenuItem 菜单Item
OrmLiteDao 数据库
RoboGuice
Trace 日志条目
Transactional 数据库事务任务
OnActivityResult Activity回调
OnActivityResult.Extra Activit回调扩展值
HierarchyViewerSupport
ServiceAction 服务信号
Receiver 广播
Receiver.Extra 广播扩展值
ReceiverAction 广播信号
ReceiverAction.Extra 广播信号扩展值
IgnoredWhenDetached
IgnoreWhen
WakeLock 锁屏
DataBound 数据绑定
七.资源注入
StringRes 字符串
AnimationRes 动画
ColorRes 颜色
DimensionPixelOffsetRes 数字
DimensionPixelSizeRes 数字
DimensionRes 数字
BooleanRes 布尔
ColorStateListRes 颜色状态
DrawableRes 图片
IntArrayRes 整型数组
IntegerRes 整型
LayoutRes 布局
MovieRes 电影
StringArrayRes 字符串数组
TextArrayRes 文本数组
TextRes 文本
HtmlRes 网页
八.结束
到这里,其实大部分常用的Api都已经有所讲解了,不过在实际开发中可能还会有一些需要注意的事项,不过不用担心,多看下wiki即可,国内的博客领域比较凌乱,其实很难找到实用的东西,所以需要自己耐心一点,当然还有Rest Api ,Typesafe SharedPreferences,Preference API helpers 这些就不讲了,感兴趣的可以看下Github wiki,一法通万法,掌握了学习知识的技巧,很多东西哪怕不了解,摸索一下也能快速上手的。
Demo下载:
https://pan.baidu.com/s/1QzkVUsIPKAv1veM9gSuwEw
密码:t35a
文章PDF下载:
https://pan.baidu.com/s/1vWsiqLyrvp4sNPg9B_9aVA
密码:vweh
推荐我的慕课网Android实战课程,助你暴力提升Android技术。
https://coding.imooc.com/class/390.html
我创建了一个关于Android的交流群,有兴趣可以加我微信我拉你
如果感觉现在的网络技术文章质量不高,苦于自己的Android技术无法得到明显的提升,感叹没有一帮好的学习伙伴及道友,那么我的知识星球可能就是一片净土,好的学习气氛,更好的技术资源与文章,自由且高效率,快来吧。