简介
Android项目架构中,随着业务的复杂越来越大,模块化/组件化是必须的。对于Activity之间的跳转希望通过注解自动实现,模仿ARouter做法,实现简单路由组件。
思路
- 创建注解lib模块,自定义注解
- 创建注解编译处理lib模块,实现添加注解标识的类和注解的映射关系
- 创建公用跳转的Router工具类
实现
- 项目中创建自定义注解module,类型为Java Library,如lib_annotation.创建自定义注解IRouter,如下
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface IRouter {
// 注解参数
String path();
}
- 项目中创建注解编译module,类型为Java Library,如lib_compiler。创建继承自AbstractProcessor的处理类并且重写方法process。
lib_compiler模块的build.gradle添加依赖:
implementation 'com.squareup:javapoet:1.11.1' //一款可以自动生成Java文件的第三方依赖
implementation 'com.google.auto.service:auto-service:1.0-rc5' //自动在META-INF文件夹下生成Processor配置信息文件
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc5'
implementation project(":lib_annotation")
重写process方法
@AutoService(value = {Processor.class})
@SupportedAnnotationTypes(value = {"com.supcon.mes.lib_annotation.IRouter"})
@SupportedSourceVersion(value = SourceVersion.RELEASE_8)
public class IActivityProcess extends AbstractProcessor {
private Filer mFiler;
private static final String ROUTER_PACKAGE = "com.supcon.mes.router";
private static final String ROUTER_NAME = "Activity_Router_Mapper";
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
mFiler = processingEnv.getFiler();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
// 获取添加IRouter注解的所有类
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(IRouter.class);
// 使用JavaPoet工具 创建注解映射类
TypeSpec.Builder builder = TypeSpec.classBuilder(ROUTER_NAME).addModifiers(PUBLIC);
for (Element annotatedElement : annotatedElements) {
// 获取注解参数path
String path = annotatedElement.getAnnotation(IRouter.class).path();
// 获取被注解的类名
String name = annotatedElement.getSimpleName().toString();
// 获取类名全称
TypeElement typeElement = (TypeElement) annotatedElement;
String className = typeElement.getQualifiedName().toString();
// 创建字段:以path为变量名,以类名为值
FieldSpec fieldSpec = FieldSpec.builder(String.class,path).addModifiers(PUBLIC).addModifiers(STATIC)
.initializer("$S",className).build();
// 将字段添加到类中
builder.addField(fieldSpec);
}
try {
// 创建Java文件
JavaFile javaFile = JavaFile.builder(ROUTER_PACKAGE,builder.build()).build();
javaFile.writeTo(mFiler);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
}
3.需要的模块引入依赖,rebuild后在相应的模块路径.../build/generated/source/apt/debug/com.supcon.mes.router/下,创建一个名为Activity_Router_Mapper的映射java文件
implementation project(":lib_annotation")
implementation project(":lib_compiler")
annotationProcessor project(":lib_compiler")
4.实现公用Router工具类
public class RouterHelper {
public static void goActivity(Context context,String path, Bundle extra){
Intent intent = new Intent(context,getActivity(path));
// intent.setClass(context,getActivity(path));
if (extra != null){
intent.putExtras(extra);
}
context.startActivity(intent);
}
private static Class<?> getActivity(String path) {
try {
Class<?> routerClass = Activity_Router_Mapper.class;
Field field = routerClass.getField(path);
return Class.forName(field.get(routerClass).toString());
} catch (NoSuchFieldException | ClassNotFoundException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
}
5.使用
@IRouter(path = Constant.Router.LOGIN)
public class LoginActivity extends AppCompatActivity {
// ...TODO
}
@IRouter(path = Constant.Router.SETTING)
public class SettingsActivity extends AppCompatActivity {
// ...TODO
}
RouterHelper.goActivity(LoginActivity.this,Constant.Router.SETTING,null);