啥是注解,不懂的可以先看我上一篇文章。
在 android 里面 注解主要用来干这么几件事:
这里使用官方的一个库,说明在开发中的简单一个应用。
在新建项目的时候会自动导的, 可以看 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'
这时候就可以使用一些 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 的一个简单功能,View 的注入: 一个注解,一个解析器即可。
- @Target(ElementType.FIELD) //解析常量
- @Retention(RetentionPolicy.RUNTIME) //运行时
- public @interface BindView {
- int value() default -1; //标识控件
- }
- /**
- * 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);
- }
- }
- }
- }
- }
- 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");
- }
- }
来源: http://blog.csdn.net/niubitianping/article/details/60575155