生也有涯,知也无涯。这篇文章主要讲述Android AOP之路三 Android上的注解相关的知识,希望能为你提供帮助。
一、简介 啥是注解,
不懂的可以先看我上一篇文章。
在android 里面 注解主要用来干这么几件事:
- 和编译器一起给你一些提示警告信息。
- 配合一些ide 可以更加方便快捷 安全有效的编写java代码。谷歌出的support-annotations这个库 就是主要干这个的。
- 和反射一起 提供一些类似于spring 可配置的功能,
方便简洁。
2.1 导包
在新建项目的时候会自动导的,可以看build.gradle中的依赖dependencies是这样的。
dependencies {
compile fileTree(dir: '
libs'
, include: ['
*.jar'
])
androidTestCompile('
com.android.support.test.espresso:espresso-core:2.2.2'
, {
exclude group: '
com.android.support'
, module: '
support-annotations'
})
compile '
com.android.support:appcompat-v7:25.1.1'
testCompile '
junit:junit:4.12'
}
如果没有的话, 自己在build.gradle的依赖添加(xx.x.x为你的compileSdkVersion版本号):
compile '
com.android.support:support-annotations:xx.x.x'
2.2 使用
这时候就可以使用一些support-annotations提供的注解, 下面举一些栗子:
1、 @ NonNull
test方法参数添加了一个NonNull注解, 然后我们传递一个空的参数过去。
public class MainActivity extends AppCompatActivity {@
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String s =
null;
test(s);
}public void test(@
NonNull String s){
System.out.println(s);
}}
IDE就会提示警告
文章图片
2、 @ StringRes
再定义testString方法参数添加了一个StringRes注解, 然后我们传递一个数字过去。
public class MainActivity extends AppCompatActivity {@
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testString(112312);
testString(R.string.app_name);
}public void testString(@
StringRes int s){
System.out.println(s);
}}
IDE就会提示
文章图片
三、实现自己的ButterKnife 【Android AOP之路三 Android上的注解】经过之前的知识, 我们已经知道注解的原理和使用了, 这里实现ButterKnife的一个简单功能, View的注入: 一个注解, 一个解析器即可。
3.1 BindView注解
@
Target(ElementType.FIELD)//解析常量
@
Retention(RetentionPolicy.RUNTIME)//运行时
public @
interface BindView {
int value() default -1;
//标识控件
}
3.2 BindViewParser解析器
/**
* Created by Litp on 2017/2/17.
*/
public class BindViewParser {/**
* 传递activty或者View 对象,
使用反射获取view变量
* @
param object
*/
public static void inject(Object object) {try {
parse(object);
} catch (Exception e) {
e.printStackTrace();
}
}/**
* 解析获取值
* @
param object
* @
throws Exception
*/
public static void parse(Object object) throws Exception {final Class<
?>
clazz =
object.getClass();
View view =
null;
//获取clazz的变量,
不论private还是public
Field[] fields =
clazz.getDeclaredFields();
for (Field field : fields) {//这个变量 是否有BindView注解
if (field.isAnnotationPresent(BindView.class)) {
//获取这个变量对应的注解
BindView injectView =
field.getAnnotation(BindView.class);
//获取值
int id =
injectView.value();
if (id <
=
0) {
throw new Exception("
View的id不能为空"
);
} else {
//设置可以访问
field.setAccessible(true);
//获取view
if (object instanceof View) {
view =
((View) object).findViewById(id);
} else if (object instanceof Activity) {
view =
((Activity) object).findViewById(id);
}
//设置View
field.set(object, view);
}}}}}
3.3 Activity使用
public class MainActivity extends AppCompatActivity {//使用注解标识变量
@
BindView(R.id.tv_test)
TextView textView;
@
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//传递当前activty给解析器,
进行初始化view
BindViewParser.inject(this);
//这里就已经是初始化完毕了,
可以进行使用了
textView.setText("
测试自己的注入demo"
);
}}
推荐阅读
- caffe之android移植
- Android WebView 自适应屏幕
- Android性能优化--关于内存溢出
- android sqlite3命令行检查自己的代码操作数据库是否正确
- 关于android(getSlotFromBufferLocked的问题)
- android 异常解决
- Android Studio工程引用第三方so文件
- 安卓动画两种基本实现方式
- Android 常用adb shell 命令(转)