编写android 注解解释器
16lz
2022-08-01
编写android 注解解释器(apt)
步骤:1. 编写注解文件2. 写注解解释器,编译时生成注解文件3. 运行时通过反射调用注解生成的类和方法
编写注解文件
@Retention(RetentionPolicy.CLASS)@Target(ElementType.TYPE)public @interface Components { String[] value();}
写注解解释器,编译时生成注解文件
@AutoService(Processor.class)public class RouterProcessor extends AbstractProcessor { private Filer mFiler; private Messager mMessager; private Map mStaticRouterMap = new HashMap<>(); private List mAutoRouterList = new ArrayList<>(); @Override public synchronized void init(ProcessingEnvironment processingEnvironment) { super.init(processingEnvironment); mFiler = processingEnvironment.getFiler(); mMessager = processingEnvironment.getMessager(); } @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latestSupported(); } @Override public Set getSupportedAnnotationTypes() { Set set = new HashSet<>(); set.add(AutoRouter.class.getCanonicalName()); set.add(StaticRouter.class.getCanonicalName()); set.add(Component.class.getCanonicalName()); set.add(Components.class.getCanonicalName()); return set; } @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) { mStaticRouterMap.clear(); mAutoRouterList.clear(); try { Set<? extends Element> mainAppElement = roundEnvironment.getElementsAnnotatedWith(Components.class); if (!mainAppElement.isEmpty()) { processInstaller(mainAppElement); return true; } processComponent(roundEnvironment); } catch (Exception e) { mMessager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); } return true; } private void processInstaller(Set<? extends Element> mainAppElement) throws IOException { TypeElement typeElement = (TypeElement) mainAppElement.iterator().next(); JavaFileObject javaFileObject = mFiler.createSourceFile(Config.ROUTER_MANAGER, typeElement); PrintWriter writer = new PrintWriter(javaFileObject.openWriter()); writer.println("package " + Config.PACKAGE_NAME + ";"); writer.println("public class " + Config.ROUTER_MANAGER + " {"); writer.println("public static void " + Config.ROUTER_MANAGER_METHOD + "() {"); Components componentsAnnotation = typeElement.getAnnotation(Components.class); String[] components = componentsAnnotation.value(); for (String item : components) { writer.println(Config.FILE_PREFIX + item + ".router();"); } writer.println("}"); writer.println("}"); writer.flush(); writer.close(); } private void processComponent(RoundEnvironment roundEnvironment) throws Exception { Set<? extends Element> compElements = roundEnvironment.getElementsAnnotatedWith(Component.class); if (compElements.isEmpty()) { return;} Element item = compElements.iterator().next(); String componentName = item.getAnnotation(Component.class).value(); Set<? extends Element> routerElements = roundEnvironment.getElementsAnnotatedWith(StaticRouter.class); for (Element e : routerElements) { if (! (e instanceof TypeElement)) { continue;} TypeElement typeElement = (TypeElement) e; String pattern = typeElement.getAnnotation(StaticRouter.class).value(); mStaticRouterMap.put(pattern, typeElement.getQualifiedName().toString()); } Set<? extends Element> autoRouterElements = roundEnvironment.getElementsAnnotatedWith(AutoRouter.class); for (Element e : autoRouterElements) { if (!(e instanceof TypeElement)) { continue;} TypeElement typeElement = (TypeElement) e; mAutoRouterList.add(typeElement.getQualifiedName().toString()); } writeComponentFile(componentName); } private void writeComponentFile(String componentName) throws Exception { String className = Config.FILE_PREFIX + componentName; JavaFileObject javaFileObject = mFiler.createSourceFile(className);// javaFileObject.delete(); PrintWriter printWriter = new PrintWriter(javaFileObject.openWriter()); printWriter.println("package " + Config.PACKAGE_NAME + ";"); printWriter.println("import android.app.Activity;"); printWriter.println("import android.app.Service;"); printWriter.println("import android.content.BroadcastReceiver;"); printWriter.println("public class " + className + " {"); printWriter.println("public static void router() {"); // // Router.router(ActivityRule.ACTIVITY_SCHEME + "shop.main", ShopActivity.class); for(Map.Entry entry : mStaticRouterMap.entrySet()) { printWriter.println("org.loader.router.Router.router(\"" + entry.getKey() +"\", "+entry.getValue()+".class);"); } for (String klass : mAutoRouterList) { printWriter.println("if (Activity.class.isAssignableFrom(" + klass + ".class)) {"); printWriter.println("org.loader.router.Router.router(org.loader.router.rule.ActivityRule.ACTIVITY_SCHEME + \"" +klass+"\", " + klass + ".class);"); printWriter.println("}"); printWriter.println("else if (Service.class.isAssignableFrom(" + klass + ".class)) {"); printWriter.println("org.loader.router.Router.router(org.loader.router.rule.ServiceRule.SERVICE_SCHEME + \"" +klass+"\", " + klass + ".class);"); printWriter.println("}"); printWriter.println("else if (BroadcastReceiver.class.isAssignableFrom(" + klass + ".class)) {"); printWriter.println("org.loader.router.Router.router(org.loader.router.rule.ReceiverRule.RECEIVER_SCHEME + \"" +klass+"\", "+klass+".class);"); printWriter.println("}"); } printWriter.println("}"); printWriter.println("}"); printWriter.flush(); printWriter.close(); }}
使用注解
@Component("bbs")public class BBS {}
编译后生成注解类
public class Router_bbs {public static void router() {if (Activity.class.isAssignableFrom(org.loader.bbslib.BBSActivity.class)) {org.loader.router.Router.router(org.loader.router.rule.ActivityRule.ACTIVITY_SCHEME + "org.loader.bbslib.BBSActivity", org.loader.bbslib.BBSActivity.class);}else if (Service.class.isAssignableFrom(org.loader.bbslib.BBSActivity.class)) {org.loader.router.Router.router(org.loader.router.rule.ServiceRule.SERVICE_SCHEME + "org.loader.bbslib.BBSActivity", org.loader.bbslib.BBSActivity.class);}else if (BroadcastReceiver.class.isAssignableFrom(org.loader.bbslib.BBSActivity.class)) {org.loader.router.Router.router(org.loader.router.rule.ReceiverRule.RECEIVER_SCHEME + "org.loader.bbslib.BBSActivity", org.loader.bbslib.BBSActivity.class);}}}
通过反射调用
public class RouterHelper { public static void install() { try { Class<?> klass = Class.forName(Config.PACKAGE_NAME + "." + Config.ROUTER_MANAGER); Method method = klass.getDeclaredMethod(Config.ROUTER_MANAGER_METHOD); method.invoke(null); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }}
更多相关文章
- android ndk编译x264开源(用于android的ffmpeg中进行软编码)
- [android]编译时出现/usr/bin/ld: skipping incompatible /usr/l
- 编译android的linux内核
- Android(安卓)命令行编译、打包生成apk文件
- Android热更新框架Tinker无法更新?
- Android(OpenCV) NDK开发: 0xdeadbaad(code=1)错误 及 关闭armea
- flutter-使用第三方库,编译和运行版本不一致问题 2
- Android(安卓)4.0.1 源码下载,编译和运行
- android:制作system.img(yaffs2)镜像