Android中简单使用aspectj
前言:
面向切面编程(AOP是Aspect Oriented Program的首字母缩写),这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程.
1.简介:
在Android中使用注解主要有以下几个作用:
- 1.和编译器一起给开发者提示警告信息
- 2.配合一些ide 可以更加方便快捷 安全有效的编写Java代码。谷歌出的support-annotations这个库 就是主要干这个的。
- 3.和反射一起 提供一些类似于spring 可配置的功能,方便简洁。
2.依赖:
2.1 导包:
在App的build目录下引入如下依赖:
implementation 'org.aspectj:aspectjrt:1.8.9'
2.2 在项目的build.gradle目录下:
classpath 'org.aspectj:aspectjtools:1.8.9'
classpath 'org.aspectj:aspectjweaver:1.8.9'
3.简单使用:
//使用注解标识变量
@MyBindView(R.id.tv_bindview_test)
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String s = "注解学习!!";
test(s);
}
private void test(@NonNull String s) {
Log.d(TAG,s);
}
4.打印日志如下:
5.自定义注解MyBindView
经过之前的知识,我们已经知道注解的原理和使用了,这里实现ButterKnife的一个简单功能,View的注入: 一个注解,一个解析器即可。
6.MyBindView注入:
/**
* @author:njb
* @date:{2021/1/2 0002} {23:11}
* @desc:MyBindView注解
*/
@Target(ElementType.FIELD) //解析常量
@Retention(RetentionPolicy.RUNTIME) //运行时
public @interface MyBindView {
int value() default -1;//标识控件
}
7.MyBindViewParser解析器
package com.example.aopstudydemo;
import android.app.Activity;
import android.view.View;
import java.lang.reflect.Field;
/**
* @author:njb
* @date:{2021/1/2
* @desc:MyBindViewParser解析器
*/
public class MyBindViewParser {
/**
* 传递activity或者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(MyBindView.class)) {
//获取这个变量对应的注解
MyBindView injectView = field.getAnnotation(MyBindView.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);
}
}
}
}
}
8.在Activity中的使用:
//使用注解标识变量
@MyBindView(R.id.tv_bindview_test)
TextView textView;
package com.example.aopstudydemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
//使用注解标识变量
@MyBindView(R.id.tv_bindview_test)
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String s = "注解学习!!";
test(s);
initView();
}
private void initView() {
//传递当前activity给解析器,进行初始化view
MyBindViewParser.inject(this);
//这里就已经是初始化完毕了,可以进行使用了
textView.setText("测试自己的注解demo");
}
private void test(@NonNull String s) {
Log.d(TAG,s);
}
}