From e40b37f66dc31896dcd19974b8601e5fed9ab487 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Wed, 8 Nov 2023 15:54:18 +0800 Subject: [PATCH 01/28] =?UTF-8?q?=E5=BC=80=E6=94=BECard=E7=B1=BB=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E6=96=B9=E6=B3=95=E7=9A=84=E8=AE=BF=E9=97=AE=E8=8C=83?= =?UTF-8?q?=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/wyjson/router/card/Card.java | 8 ++++++-- .../src/main/java/com/wyjson/router/card/CardMeta.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java b/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java index f72d920..6b4f432 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java @@ -35,7 +35,7 @@ public final class Card extends CardMeta { private Throwable interceptorException;// 拦截执行中断异常信息 private int timeout = 300;// go() timeout, TimeUnit.Second - private void setUri(Uri uri) { + public void setUri(Uri uri) { this.uri = uri; setPath(uri.getPath()); } @@ -299,8 +299,12 @@ public int getTimeout() { return timeout; } - public void setTimeout(int timeout) { + /** + * @param timeout Second + */ + public Card setTimeout(int timeout) { this.timeout = timeout; + return this; } @NonNull diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java b/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java index 6e3dc6d..f5d7674 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java @@ -36,7 +36,7 @@ public String getPath() { return path; } - protected void setPath(@NonNull String path) { + public void setPath(@NonNull String path) { this.path = path; } From 3cf8b1b2089e5508b8e0a3b14915016e02801097 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Wed, 8 Nov 2023 18:56:11 +0800 Subject: [PATCH 02/28] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=88=86=E7=BB=84?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wyjson/router/load/IRouteModuleGroup.java | 9 +++++ .../router/compiler/utils/Constants.java | 2 + module_common/build.gradle | 8 ++-- .../wyjson/module_common/route/UserRoute.java | 8 +++- module_main/build.gradle | 4 +- .../module_main/activity/RouteGroupTest.java | 40 +++++++++++++++++++ module_user/build.gradle | 4 +- 7 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModuleGroup.java create mode 100644 module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModuleGroup.java b/GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModuleGroup.java new file mode 100644 index 0000000..c541e35 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModuleGroup.java @@ -0,0 +1,9 @@ +package com.wyjson.router.load; + +/** + * Do not use this interface. + * This interface is used to automatically generate routing tables and load class routing groups! + */ +public interface IRouteModuleGroup { + void load(); +} \ No newline at end of file diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java index 2032f94..36b8667 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java @@ -6,6 +6,8 @@ public class Constants { public static final String SEPARATOR = "$$"; public static final String WARNING_TIPS = "DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY GOROUTER."; public static final String METHOD_NAME_LOAD = "load"; + public static final String METHOD_NAME_LOAD_ROUTE_GROUP = "loadRouteGroup"; + public static final String METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP = "loadRouteFor%sGroup"; // System interface public static final String ACTIVITY = "android.app.Activity"; diff --git a/module_common/build.gradle b/module_common/build.gradle index aaf1f7c..67d1444 100644 --- a/module_common/build.gradle +++ b/module_common/build.gradle @@ -36,9 +36,9 @@ android { dependencies { api 'androidx.appcompat:appcompat:1.6.1' -// api project(path: ':GoRouter-Api') -// annotationProcessor project(path: ':GoRouter-Compiler') + api project(path: ':GoRouter-Api') + annotationProcessor project(path: ':GoRouter-Compiler') - api "com.github.wyjsonGo.GoRouter:GoRouter-Api:${VERSION}" - annotationProcessor "com.github.wyjsonGo.GoRouter:GoRouter-Compiler:${VERSION}" +// api "com.github.wyjsonGo.GoRouter:GoRouter-Api:${VERSION}" +// annotationProcessor "com.github.wyjsonGo.GoRouter:GoRouter-Compiler:${VERSION}" } \ No newline at end of file diff --git a/module_common/src/main/java/com/wyjson/module_common/route/UserRoute.java b/module_common/src/main/java/com/wyjson/module_common/route/UserRoute.java index 06593e2..2da157b 100755 --- a/module_common/src/main/java/com/wyjson/module_common/route/UserRoute.java +++ b/module_common/src/main/java/com/wyjson/module_common/route/UserRoute.java @@ -6,9 +6,13 @@ public interface UserRoute extends BaseRoute { String PREFIX = "/user"; String SignInActivity = PREFIX + "/sign_in" + ACTIVITY_ROUTE_SUFFIX; - String ParamActivity = PREFIX + "/param" + ACTIVITY_ROUTE_SUFFIX; String CardFragment = PREFIX + "/card" + FRAGMENT_ROUTE_SUFFIX; - String ParamFragment = PREFIX + "/param" + FRAGMENT_ROUTE_SUFFIX; String UserInfoActivity = PREFIX + "/info" + ACTIVITY_ROUTE_SUFFIX; + /** + * 主要为了演示一个模块下多个路由分组 + */ + String NEW_PREFIX = "/new"; + String ParamActivity = NEW_PREFIX + "/param" + ACTIVITY_ROUTE_SUFFIX; + String ParamFragment = NEW_PREFIX + "/param" + FRAGMENT_ROUTE_SUFFIX; } \ No newline at end of file diff --git a/module_main/build.gradle b/module_main/build.gradle index 6f1d9b0..91ef92f 100644 --- a/module_main/build.gradle +++ b/module_main/build.gradle @@ -38,6 +38,6 @@ android { dependencies { api project(path: ':module_common') -// annotationProcessor project(path: ':GoRouter-Compiler') - annotationProcessor "com.github.wyjsonGo.GoRouter:GoRouter-Compiler:${VERSION}" + annotationProcessor project(path: ':GoRouter-Compiler') +// annotationProcessor "com.github.wyjsonGo.GoRouter:GoRouter-Compiler:${VERSION}" } \ No newline at end of file diff --git a/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java b/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java new file mode 100644 index 0000000..08a75e5 --- /dev/null +++ b/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java @@ -0,0 +1,40 @@ +package com.wyjson.module_main.activity; + +import android.util.ArrayMap; + +import com.wyjson.router.load.IRouteModuleGroup; + +import java.util.Map; + +public class RouteGroupTest { + + public void load() { + //... + loadRouteGroup(); + } + + Map routeGroups = new ArrayMap<>(); + + private void loadRouteGroup() { + routeGroups.put("my", new IRouteModuleGroup() { + @Override + public void load() { + // loadRouteForMyGroup() + } + }); + routeGroups.put("user", new IRouteModuleGroup() { + @Override + public void load() { + // loadRouteForUserGroup() + } + }); + } + + private void loadRouteForMyGroup() { + // commit() + } + + private void loadRouteForUserGroup() { + // commit() + } +} diff --git a/module_user/build.gradle b/module_user/build.gradle index 8a15ce5..0be4006 100644 --- a/module_user/build.gradle +++ b/module_user/build.gradle @@ -38,6 +38,6 @@ android { dependencies { api project(path: ':module_common') -// annotationProcessor project(path: ':GoRouter-Compiler') - annotationProcessor "com.github.wyjsonGo.GoRouter:GoRouter-Compiler:${VERSION}" + annotationProcessor project(path: ':GoRouter-Compiler') +// annotationProcessor "com.github.wyjsonGo.GoRouter:GoRouter-Compiler:${VERSION}" } From 983943ecfb5a2fec262978d30e1420d09d3f95c2 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Thu, 9 Nov 2023 14:12:45 +0800 Subject: [PATCH 03/28] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=B1=BBCompiler=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../router/compiler/doc/DocumentUtils.java | 14 +- .../GenerateModuleRouteProcessor.java | 173 ++++++++++-------- 2 files changed, 108 insertions(+), 79 deletions(-) diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java index a5cbdd6..e20a905 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java @@ -50,7 +50,7 @@ public static void createDoc(Filer mFiler, String moduleName, Logger logger, boo } } - public static void generate(String moduleName, Logger logger) { + public static void generateDoc(String moduleName, Logger logger) { if (!isDocEnable) return; try { @@ -62,7 +62,7 @@ public static void generate(String moduleName, Logger logger) { } } - public static void addService(String moduleName, Logger logger, Element element, Service service) { + public static void addServiceDoc(String moduleName, Logger logger, Element element, Service service) { if (!isDocEnable) return; try { @@ -74,7 +74,7 @@ public static void addService(String moduleName, Logger logger, Element element, } } - public static void addInterceptor(String moduleName, Logger logger, Element element, Interceptor interceptor) { + public static void addInterceptorDoc(String moduleName, Logger logger, Element element, Interceptor interceptor) { if (!isDocEnable) return; try { @@ -84,7 +84,7 @@ public static void addInterceptor(String moduleName, Logger logger, Element elem } } - public static void addRoute(String moduleName, Logger logger, Element element, Route route, String typeDoc) { + public static void addRouteDoc(String moduleName, Logger logger, Element element, Route route, String typeDoc) { if (!isDocEnable) return; try { @@ -96,14 +96,14 @@ public static void addRoute(String moduleName, Logger logger, Element element, R if (route.tag() != 0) { routeModel.setTag(route.tag()); } - addParam(moduleName, logger, element, routeModel); + addParamCode(moduleName, logger, element, routeModel); documentModel.getRoutes().add(routeModel); } catch (Exception e) { logger.error(moduleName + " Failed to add route [" + element.toString() + "] document, " + e.getMessage()); } } - private static void addParam(String moduleName, Logger logger, Element element, RouteModel routeModel) { + private static void addParamCode(String moduleName, Logger logger, Element element, RouteModel routeModel) { List tempParamModels = new ArrayList<>(); for (Element field : element.getEnclosedElements()) { if (field.getKind().isField() && field.getAnnotation(Param.class) != null) { @@ -148,7 +148,7 @@ private static void addParam(String moduleName, Logger logger, Element element, if (parent instanceof DeclaredType) { Element parentElement = ((DeclaredType) parent).asElement(); if (parentElement instanceof TypeElement && !((TypeElement) parentElement).getQualifiedName().toString().startsWith("android")) { - addParam(moduleName, logger, parentElement, routeModel); + addParamCode(moduleName, logger, parentElement, routeModel); } } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index 719378f..29db760 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -19,6 +19,7 @@ import static com.wyjson.router.compiler.utils.Constants.LONG_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.LONG_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_GROUP; import static com.wyjson.router.compiler.utils.Constants.MODULE_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.PARCELABLE_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.PREFIX_OF_LOGGER; @@ -29,10 +30,12 @@ import static com.wyjson.router.compiler.utils.Constants.SHORT_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.STRING_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.WARNING_TIPS; +import static javax.lang.model.element.Modifier.PRIVATE; import static javax.lang.model.element.Modifier.PUBLIC; import com.google.auto.service.AutoService; import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeSpec; @@ -95,11 +98,12 @@ public boolean process(Set set, RoundEnvironment roundEnv MethodSpec.Builder loadInto = MethodSpec.methodBuilder(METHOD_NAME_LOAD) .addModifiers(PUBLIC) .addAnnotation(Override.class); - loadInto.addJavadoc("Load the $S route", moduleName); + loadInto.addJavadoc("load the $S route", moduleName); addService(roundEnvironment, loadInto); addInterceptor(roundEnvironment, loadInto); addRoute(roundEnvironment, loadInto); + LinkedHashSet routeGroupMethods = addRouteGroup(roundEnvironment, loadInto); String className = generateClassName + SEPARATOR + PROJECT; try { @@ -109,6 +113,7 @@ public boolean process(Set set, RoundEnvironment roundEnv .addSuperinterface(ClassName.get(mIRouteModule)) .addJavadoc(WARNING_TIPS) .addMethod(loadInto.build()) + .addMethods(routeGroupMethods) .build() ).indent(" ").build().writeTo(mFiler); @@ -118,7 +123,7 @@ public boolean process(Set set, RoundEnvironment roundEnv logger.error(e); } - DocumentUtils.generate(moduleName, logger); + DocumentUtils.generateDoc(moduleName, logger); return true; } @@ -132,7 +137,7 @@ private void addService(RoundEnvironment roundEnvironment, MethodSpec.Builder lo for (Element element : elements) { Service service = element.getAnnotation(Service.class); loadInto.addStatement("$T.getInstance().addService($T.class)", mGoRouter, element); - DocumentUtils.addService(moduleName, logger, element, service); + DocumentUtils.addServiceDoc(moduleName, logger, element, service); } } @@ -146,10 +151,20 @@ private void addInterceptor(RoundEnvironment roundEnvironment, MethodSpec.Builde for (Element element : elements) { Interceptor interceptor = element.getAnnotation(Interceptor.class); loadInto.addStatement("$T.getInstance().addInterceptor(" + interceptor.priority() + ", $T.class)", mGoRouter, element); - DocumentUtils.addInterceptor(moduleName, logger, element, interceptor); + DocumentUtils.addInterceptorDoc(moduleName, logger, element, interceptor); } } + private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { + LinkedHashSet methodSpecs = new LinkedHashSet<>(); + MethodSpec.Builder loadRouteGroup = MethodSpec.methodBuilder(METHOD_NAME_LOAD_ROUTE_GROUP).addModifiers(PRIVATE); + loadRouteGroup.addJavadoc("load route group"); + + loadInto.addStatement("$N()", loadRouteGroup.build()); + methodSpecs.add(loadRouteGroup.build()); + return methodSpecs; + } + private void addRoute(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { Set elements = roundEnvironment.getElementsAnnotatedWith(Route.class); if (CollectionUtils.isEmpty(elements)) @@ -164,108 +179,122 @@ private void addRoute(RoundEnvironment roundEnvironment, MethodSpec.Builder load Route route = element.getAnnotation(Route.class); TypeMirror tm = element.asType(); +// String typeDoc; +// String type; +// // handle type +// if (types.isSubtype(tm, typeActivity)) { +// typeDoc = "Activity"; +// type = ".commitActivity($T.class)"; +// } else if (types.isSubtype(tm, typeFragment)) { +// typeDoc = "Fragment"; +// type = ".commitFragment($T.class)"; +// } else { +// throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') is marked on unsupported class, look at [" + tm.toString() + "]."); +// } +// +// String tag = route.tag() == 0 ? "" : ".putTag(" + route.tag() + ")"; +// +// // Get all fields annotation by @Param +// String param = ""; +// try { +// param = handleParam(new StringBuilder(), element); +// } catch (Exception e) { +// throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); +// } +// loadInto.addStatement("$T.getInstance().build($S)" + tag + param + type, mGoRouter, route.path(), element); +// DocumentUtils.addRoute(moduleName, logger, element, route, typeDoc); + + CodeBlock.Builder unifyCode = CodeBlock.builder(); + // GoRouter.getInstance().build(xxx) + CodeBlock.Builder buildCode = CodeBlock.builder().add("$T.getInstance().build($S)", mGoRouter, route.path()); + unifyCode.add(buildCode.build()); + + // .putTag(x) + CodeBlock.Builder tagCode = CodeBlock.builder(); + if (route.tag() != 0) { + tagCode.add(".putTag($L)", route.tag()); + } + unifyCode.add(tagCode.build()); + + // .putInt(x).putString(x) ... + // Get all fields annotation by @Param + CodeBlock.Builder paramCode = CodeBlock.builder(); + try { + paramCode = handleParam(paramCode, element); + } catch (Exception e) { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); + } + unifyCode.add(paramCode.build()); + + // .commitXXX(x) String typeDoc; - String type; - // handle type + CodeBlock.Builder typeCode = CodeBlock.builder(); if (types.isSubtype(tm, typeActivity)) { typeDoc = "Activity"; - type = ".commitActivity($T.class)"; + typeCode.add(".commitActivity($T.class)", element); } else if (types.isSubtype(tm, typeFragment)) { typeDoc = "Fragment"; - type = ".commitFragment($T.class)"; + typeCode.add(".commitFragment($T.class)", element); } else { throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') is marked on unsupported class, look at [" + tm.toString() + "]."); } + unifyCode.add(typeCode.build()); - String tag = route.tag() == 0 ? "" : ".putTag(" + route.tag() + ")"; - - // Get all fields annotation by @Param - String param = ""; - try { - param = handleParam(new StringBuilder(), element); - } catch (Exception e) { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); - } - loadInto.addStatement("$T.getInstance().build($S)" + tag + param + type, mGoRouter, route.path(), element); - DocumentUtils.addRoute(moduleName, logger, element, route, typeDoc); + loadInto.addStatement(unifyCode.build()); + DocumentUtils.addRouteDoc(moduleName, logger, element, route, typeDoc); } } - private String handleParam(StringBuilder paramSB, Element element) { - StringBuilder tempParamSB = new StringBuilder(); + private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element element) { + CodeBlock.Builder tempParamCode = CodeBlock.builder(); for (Element field : element.getEnclosedElements()) { // It must be field, then it has annotation if (field.getKind().isField() && field.getAnnotation(Param.class) != null) { Param param = field.getAnnotation(Param.class); - String paramName = field.getSimpleName().toString(); + String key = field.getSimpleName().toString(); TypeMirror typeMirror = field.asType(); String typeStr = typeMirror.toString(); + String paramType; switch (typeStr) { - case BYTE_PACKAGE: - case BYTE_PRIMITIVE: - tempParamSB.append(".putByte("); - break; - case SHORT_PACKAGE: - case SHORT_PRIMITIVE: - tempParamSB.append(".putShort("); - break; - case INTEGER_PACKAGE: - case INTEGER_PRIMITIVE: - tempParamSB.append(".putInt("); - break; - case LONG_PACKAGE: - case LONG_PRIMITIVE: - tempParamSB.append(".putLong("); - break; - case FLOAT_PACKAGE: - case FLOAT_PRIMITIVE: - tempParamSB.append(".putFloat("); - break; - case DOUBEL_PACKAGE: - case DOUBEL_PRIMITIVE: - tempParamSB.append(".putDouble("); - break; - case BOOLEAN_PACKAGE: - case BOOLEAN_PRIMITIVE: - tempParamSB.append(".putBoolean("); - break; - case CHAR_PACKAGE: - case CHAR_PRIMITIVE: - tempParamSB.append(".putChar("); - break; - case STRING_PACKAGE: - tempParamSB.append(".putString("); - break; - default: + case BYTE_PACKAGE, BYTE_PRIMITIVE -> paramType = "putByte"; + case SHORT_PACKAGE, SHORT_PRIMITIVE -> paramType = "putShort"; + case INTEGER_PACKAGE, INTEGER_PRIMITIVE -> paramType = "putInt"; + case LONG_PACKAGE, LONG_PRIMITIVE -> paramType = "putLong"; + case FLOAT_PACKAGE, FLOAT_PRIMITIVE -> paramType = "putFloat"; + case DOUBEL_PACKAGE, DOUBEL_PRIMITIVE -> paramType = "putDouble"; + case BOOLEAN_PACKAGE, BOOLEAN_PRIMITIVE -> paramType = "putBoolean"; + case CHAR_PACKAGE, CHAR_PRIMITIVE -> paramType = "putChar"; + case STRING_PACKAGE -> paramType = "putString"; + default -> { if (types.isSubtype(typeMirror, parcelableType)) { - tempParamSB.append(".putParcelable("); + paramType = "putParcelable"; } else if (types.isSubtype(typeMirror, serializableType)) { - tempParamSB.append(".putSerializable("); + paramType = "putSerializable"; } else { - throw new RuntimeException("@Param(type='" + typeMirror.toString() + "') is marked as an unsupported type"); + throw new RuntimeException("@Param(type='" + typeMirror + "') is marked as an unsupported type"); } - break; + } } if (StringUtils.isEmpty(param.name()) && !param.required()) { - tempParamSB.append("\"").append(paramName).append("\"").append(")"); + tempParamCode.add(".$N($S)", paramType, key); } else { - tempParamSB.append("\"").append(paramName).append("\"").append(", "); if (!StringUtils.isEmpty(param.name())) { - tempParamSB.append("\"").append(param.name()).append("\"").append(", "); + tempParamCode.add(".$N($S, $S, $L)", paramType, key, param.name(), param.required()); } else { - tempParamSB.append("null").append(", "); + tempParamCode.add(".$N($S, $L, $L)", paramType, key, "null", param.required()); } - tempParamSB.append(param.required()).append(")"); } } } // Processing subclass parameters overrides parent class parameters - if (StringUtils.isEmpty(paramSB)) { - paramSB.append(tempParamSB); + if (paramCode.isEmpty()) { + paramCode.add(tempParamCode.build()); } else { - paramSB.insert(0, tempParamSB); + tempParamCode.add(paramCode.build()); + paramCode.clear(); + paramCode.add(tempParamCode.build()); } // if has parent? @@ -273,10 +302,10 @@ private String handleParam(StringBuilder paramSB, Element element) { if (parent instanceof DeclaredType) { Element parentElement = ((DeclaredType) parent).asElement(); if (parentElement instanceof TypeElement && !((TypeElement) parentElement).getQualifiedName().toString().startsWith("android")) { - return handleParam(paramSB, parentElement); + return handleParam(paramCode, parentElement); } } - return paramSB.toString(); + return paramCode; } } From dddf084f35a4c01782fd11434e3bf9f9e741e1d3 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Thu, 9 Nov 2023 19:10:19 +0800 Subject: [PATCH 04/28] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=88=86=E7=BB=84compi?= =?UTF-8?q?ler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GenerateModuleRouteProcessor.java | 270 +++++++++++------- .../router/compiler/utils/Constants.java | 27 +- .../module_main/activity/RouteGroupTest.java | 40 --- 3 files changed, 186 insertions(+), 151 deletions(-) delete mode 100644 module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index 29db760..af2e85f 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -9,16 +9,20 @@ import static com.wyjson.router.compiler.utils.Constants.CHAR_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.DOUBEL_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.DOUBEL_PRIMITIVE; +import static com.wyjson.router.compiler.utils.Constants.FIELD_NAME_ROUTE_GROUPS; import static com.wyjson.router.compiler.utils.Constants.FLOAT_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.FLOAT_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.FRAGMENT; import static com.wyjson.router.compiler.utils.Constants.GOROUTER_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.INTEGER_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.INTEGER_PRIMITIVE; +import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD; +import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_GROUP_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.LONG_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.LONG_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_GROUP; import static com.wyjson.router.compiler.utils.Constants.MODULE_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.PARCELABLE_PACKAGE; @@ -36,8 +40,10 @@ import com.google.auto.service.AutoService; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; import com.wyjson.router.annotation.Interceptor; import com.wyjson.router.annotation.Param; @@ -49,13 +55,18 @@ import org.apache.commons.lang3.StringUtils; import java.io.IOException; +import java.util.Comparator; +import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; +import java.util.TreeSet; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; @@ -65,8 +76,12 @@ public class GenerateModuleRouteProcessor extends BaseProcessor { TypeElement mGoRouter; TypeElement mIRouteModule; + TypeElement mIRouteModuleGroup; TypeMirror serializableType; TypeMirror parcelableType; + TypeMirror activityType; + TypeMirror fragmentType; + private final Map> routeGroupMap = new HashMap<>(); @Override public Set getSupportedAnnotationTypes() { @@ -84,8 +99,11 @@ public synchronized void init(ProcessingEnvironment processingEnv) { logger.info(moduleName + " >>> GenerateModuleRouteProcessor init. <<<"); mGoRouter = elementUtils.getTypeElement(GOROUTER_PACKAGE_NAME); mIRouteModule = elementUtils.getTypeElement(I_ROUTE_MODULE_PACKAGE_NAME); + mIRouteModuleGroup = elementUtils.getTypeElement(I_ROUTE_MODULE_GROUP_PACKAGE_NAME); serializableType = elementUtils.getTypeElement(SERIALIZABLE_PACKAGE).asType(); parcelableType = elementUtils.getTypeElement(PARCELABLE_PACKAGE).asType(); + activityType = elementUtils.getTypeElement(ACTIVITY).asType(); + fragmentType = elementUtils.getTypeElement(FRAGMENT).asType(); } @Override @@ -95,28 +113,27 @@ public boolean process(Set set, RoundEnvironment roundEnv DocumentUtils.createDoc(mFiler, moduleName, logger, isGenerateDoc); - MethodSpec.Builder loadInto = MethodSpec.methodBuilder(METHOD_NAME_LOAD) + String className = generateClassName + SEPARATOR + PROJECT; + TypeSpec.Builder thisClass = TypeSpec.classBuilder(className) + .addModifiers(PUBLIC) + .addSuperinterface(ClassName.get(mIRouteModule)) + .addJavadoc(WARNING_TIPS); + + MethodSpec.Builder loadIntoMethod = MethodSpec.methodBuilder(METHOD_NAME_LOAD) .addModifiers(PUBLIC) .addAnnotation(Override.class); - loadInto.addJavadoc("load the $S route", moduleName); + loadIntoMethod.addJavadoc("load the $S route", moduleName); - addService(roundEnvironment, loadInto); - addInterceptor(roundEnvironment, loadInto); - addRoute(roundEnvironment, loadInto); - LinkedHashSet routeGroupMethods = addRouteGroup(roundEnvironment, loadInto); + addService(roundEnvironment, loadIntoMethod); + addInterceptor(roundEnvironment, loadIntoMethod); + LinkedHashSet routeGroupMethods = addRouteGroup(roundEnvironment, thisClass, loadIntoMethod); - String className = generateClassName + SEPARATOR + PROJECT; + thisClass.addMethod(loadIntoMethod.build()).addMethods(routeGroupMethods); try { - JavaFile.builder(MODULE_PACKAGE_NAME, - TypeSpec.classBuilder(className) - .addModifiers(PUBLIC) - .addSuperinterface(ClassName.get(mIRouteModule)) - .addJavadoc(WARNING_TIPS) - .addMethod(loadInto.build()) - .addMethods(routeGroupMethods) - .build() - ).indent(" ").build().writeTo(mFiler); - + JavaFile.builder(MODULE_PACKAGE_NAME, thisClass.build()) + .indent(" ") + .build() + .writeTo(mFiler); logger.info(moduleName + " >>> GenerateModuleRouteProcessor over. <<<"); } catch (IOException e) { logger.error(moduleName + " Failed to generate [" + className + "] class!"); @@ -127,124 +144,177 @@ public boolean process(Set set, RoundEnvironment roundEnv return true; } - private void addService(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { + private void addService(RoundEnvironment roundEnvironment, MethodSpec.Builder loadIntoMethod) { Set elements = roundEnvironment.getElementsAnnotatedWith(Service.class); if (CollectionUtils.isEmpty(elements)) return; logger.info(moduleName + " >>> Found Service, size is " + elements.size() + " <<<"); - loadInto.addCode("// add Service\n"); + loadIntoMethod.addCode("// add Service\n"); for (Element element : elements) { Service service = element.getAnnotation(Service.class); - loadInto.addStatement("$T.getInstance().addService($T.class)", mGoRouter, element); + loadIntoMethod.addStatement("$T.getInstance().addService($T.class)", mGoRouter, element); DocumentUtils.addServiceDoc(moduleName, logger, element, service); } } - private void addInterceptor(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { + private void addInterceptor(RoundEnvironment roundEnvironment, MethodSpec.Builder loadIntoMethod) { Set elements = roundEnvironment.getElementsAnnotatedWith(Interceptor.class); if (CollectionUtils.isEmpty(elements)) return; logger.info(moduleName + " >>> Found Interceptor, size is " + elements.size() + " <<<"); - loadInto.addCode("// add Interceptor\n"); + loadIntoMethod.addCode("// add Interceptor\n"); for (Element element : elements) { Interceptor interceptor = element.getAnnotation(Interceptor.class); - loadInto.addStatement("$T.getInstance().addInterceptor(" + interceptor.priority() + ", $T.class)", mGoRouter, element); + loadIntoMethod.addStatement("$T.getInstance().addInterceptor(" + interceptor.priority() + ", $T.class)", mGoRouter, element); DocumentUtils.addInterceptorDoc(moduleName, logger, element, interceptor); } } - private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { - LinkedHashSet methodSpecs = new LinkedHashSet<>(); - MethodSpec.Builder loadRouteGroup = MethodSpec.methodBuilder(METHOD_NAME_LOAD_ROUTE_GROUP).addModifiers(PRIVATE); - loadRouteGroup.addJavadoc("load route group"); - - loadInto.addStatement("$N()", loadRouteGroup.build()); - methodSpecs.add(loadRouteGroup.build()); - return methodSpecs; - } + private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironment, TypeSpec.Builder thisClass, MethodSpec.Builder loadIntoMethod) { + LinkedHashSet routeGroupMethods = new LinkedHashSet<>(); - private void addRoute(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { Set elements = roundEnvironment.getElementsAnnotatedWith(Route.class); if (CollectionUtils.isEmpty(elements)) - return; + return routeGroupMethods; logger.info(moduleName + " >>> Found Route, size is " + elements.size() + " <<<"); - TypeMirror typeActivity = elementUtils.getTypeElement(ACTIVITY).asType(); - TypeMirror typeFragment = elementUtils.getTypeElement(FRAGMENT).asType(); + FieldSpec routeGroupsField = FieldSpec.builder( + ParameterizedTypeName.get( + ClassName.get(Map.class), + ClassName.get(String.class), + ClassName.get(mIRouteModuleGroup) + ), + FIELD_NAME_ROUTE_GROUPS, + Modifier.PRIVATE + ) + .initializer("new $T()", ClassName.get(HashMap.class)) + .build(); + thisClass.addField(routeGroupsField); + + MethodSpec.Builder loadRouteGroupMethod = MethodSpec.methodBuilder(METHOD_NAME_LOAD_ROUTE_GROUP).addModifiers(PRIVATE); + loadRouteGroupMethod.addJavadoc("load route group"); + loadRouteGroupMethod.addStatement("$N.clear()", routeGroupsField); + + saveRouteGroup(elements); + + for (Map.Entry> entry : routeGroupMap.entrySet()) { + String groupName = entry.getKey(); + // 首字母大写 + String groupNameToUpperCase = groupName.substring(0, 1).toUpperCase() + groupName.substring(1); + String methodName = String.format(METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP, groupNameToUpperCase); + MethodSpec.Builder loadRouteForXGroupMethod = MethodSpec.methodBuilder(methodName).addModifiers(PRIVATE); + loadRouteForXGroupMethod.addJavadoc("\"" + groupName + "\" route group"); + for (Element element : entry.getValue()) { + addRoute(element, loadRouteForXGroupMethod); + } + MethodSpec loadRouteForXGroupMethodBuild = loadRouteForXGroupMethod.build(); + routeGroupMethods.add(loadRouteForXGroupMethodBuild); + + // 把每个路由分组方法汇总到loadRouteGroup方法中 + CodeBlock.Builder iRouteModuleGroupCode = CodeBlock.builder(); + iRouteModuleGroupCode.beginControlFlow("new $N()", ClassName.get(mIRouteModuleGroup).simpleName()); + iRouteModuleGroupCode.indent().add("@Override\n"); + iRouteModuleGroupCode.beginControlFlow("public void $N()", I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD); + iRouteModuleGroupCode.indent().addStatement("$N()", loadRouteForXGroupMethodBuild.name); + iRouteModuleGroupCode.unindent().endControlFlow(); + iRouteModuleGroupCode.add("}"); + + CodeBlock.Builder routeGroupPutCode = CodeBlock.builder(); + routeGroupPutCode.add("$N.put($S, $N)", routeGroupsField, groupName, iRouteModuleGroupCode.build().toString()); + + loadRouteGroupMethod.addStatement(routeGroupPutCode.build()); + } + + loadIntoMethod.addCode("// call load route group\n"); + loadIntoMethod.addStatement("$N()", loadRouteGroupMethod.build()); + routeGroupMethods.add(loadRouteGroupMethod.build()); + return routeGroupMethods; + } - loadInto.addCode("// add Route\n"); + private void saveRouteGroup(Set elements) { + routeGroupMap.clear(); for (Element element : elements) { Route route = element.getAnnotation(Route.class); - TypeMirror tm = element.asType(); - -// String typeDoc; -// String type; -// // handle type -// if (types.isSubtype(tm, typeActivity)) { -// typeDoc = "Activity"; -// type = ".commitActivity($T.class)"; -// } else if (types.isSubtype(tm, typeFragment)) { -// typeDoc = "Fragment"; -// type = ".commitFragment($T.class)"; -// } else { -// throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') is marked on unsupported class, look at [" + tm.toString() + "]."); -// } -// -// String tag = route.tag() == 0 ? "" : ".putTag(" + route.tag() + ")"; -// -// // Get all fields annotation by @Param -// String param = ""; -// try { -// param = handleParam(new StringBuilder(), element); -// } catch (Exception e) { -// throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); -// } -// loadInto.addStatement("$T.getInstance().build($S)" + tag + param + type, mGoRouter, route.path(), element); -// DocumentUtils.addRoute(moduleName, logger, element, route, typeDoc); - - CodeBlock.Builder unifyCode = CodeBlock.builder(); - // GoRouter.getInstance().build(xxx) - CodeBlock.Builder buildCode = CodeBlock.builder().add("$T.getInstance().build($S)", mGoRouter, route.path()); - unifyCode.add(buildCode.build()); - - // .putTag(x) - CodeBlock.Builder tagCode = CodeBlock.builder(); - if (route.tag() != 0) { - tagCode.add(".putTag($L)", route.tag()); - } - unifyCode.add(tagCode.build()); - - // .putInt(x).putString(x) ... - // Get all fields annotation by @Param - CodeBlock.Builder paramCode = CodeBlock.builder(); - try { - paramCode = handleParam(paramCode, element); - } catch (Exception e) { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); - } - unifyCode.add(paramCode.build()); - - // .commitXXX(x) - String typeDoc; - CodeBlock.Builder typeCode = CodeBlock.builder(); - if (types.isSubtype(tm, typeActivity)) { - typeDoc = "Activity"; - typeCode.add(".commitActivity($T.class)", element); - } else if (types.isSubtype(tm, typeFragment)) { - typeDoc = "Fragment"; - typeCode.add(".commitFragment($T.class)", element); + String group = extractRouteGroup(route.path()); + Set routeSet = routeGroupMap.get(group); + if (CollectionUtils.isEmpty(routeSet)) { + Set sortRouteSet = new TreeSet<>(new Comparator() { + @Override + public int compare(Element r1, Element r2) { + String r1Path = r1.getAnnotation(Route.class).path(); + String r2Path = r2.getAnnotation(Route.class).path(); + return r1Path.compareTo(r2Path); + } + }); + sortRouteSet.add(element); + routeGroupMap.put(group, sortRouteSet); } else { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') is marked on unsupported class, look at [" + tm.toString() + "]."); + routeSet.add(element); } - unifyCode.add(typeCode.build()); + } + } - loadInto.addStatement(unifyCode.build()); - DocumentUtils.addRouteDoc(moduleName, logger, element, route, typeDoc); + private String extractRouteGroup(String path) { + if (StringUtils.isEmpty(path) || !path.startsWith("/")) { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The path[" + path + "] must be start with '/' and not empty!"); + } + try { + String group = path.substring(1, path.indexOf("/", 1)); + if (StringUtils.isEmpty(group)) { + throw new RuntimeException("The group is empty!"); + } + return group; + } catch (Exception e) { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Failed to extract the path[" + path + "] group. The path must have at least two levels '/xx/xx' and start with '/'! " + e.getMessage()); } } + private void addRoute(Element element, MethodSpec.Builder loadRouteGroupMethod) { + Route route = element.getAnnotation(Route.class); + TypeMirror tm = element.asType(); + + CodeBlock.Builder unifyCode = CodeBlock.builder(); + // GoRouter.getInstance().build(xxx) + CodeBlock.Builder buildCode = CodeBlock.builder().add("$T.getInstance().build($S)", mGoRouter, route.path()); + unifyCode.add(buildCode.build()); + + // .putTag(x) + CodeBlock.Builder tagCode = CodeBlock.builder(); + if (route.tag() != 0) { + tagCode.add(".putTag($L)", route.tag()); + } + unifyCode.add(tagCode.build()); + + // .putInt(x).putString(x) ... + // Get all fields annotation by @Param + CodeBlock.Builder paramCode = CodeBlock.builder(); + try { + paramCode = handleParam(paramCode, element); + } catch (Exception e) { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); + } + unifyCode.add(paramCode.build()); + + // .commitXXX(x) + String typeDoc; + CodeBlock.Builder typeCode = CodeBlock.builder(); + if (types.isSubtype(tm, activityType)) { + typeDoc = "Activity"; + typeCode.add(".commitActivity($T.class)", element); + } else if (types.isSubtype(tm, fragmentType)) { + typeDoc = "Fragment"; + typeCode.add(".commitFragment($T.class)", element); + } else { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') is marked on unsupported class, look at [" + tm.toString() + "]."); + } + unifyCode.add(typeCode.build()); + + loadRouteGroupMethod.addStatement(unifyCode.build()); + DocumentUtils.addRouteDoc(moduleName, logger, element, route, typeDoc); + } + private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element element) { CodeBlock.Builder tempParamCode = CodeBlock.builder(); for (Element field : element.getEnclosedElements()) { @@ -282,7 +352,7 @@ private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element eleme if (!StringUtils.isEmpty(param.name())) { tempParamCode.add(".$N($S, $S, $L)", paramType, key, param.name(), param.required()); } else { - tempParamCode.add(".$N($S, $L, $L)", paramType, key, "null", param.required()); + tempParamCode.add(".$N($S, null, $L)", paramType, key, param.required()); } } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java index 36b8667..49ea391 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java @@ -8,6 +8,7 @@ public class Constants { public static final String METHOD_NAME_LOAD = "load"; public static final String METHOD_NAME_LOAD_ROUTE_GROUP = "loadRouteGroup"; public static final String METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP = "loadRouteFor%sGroup"; + public static final String FIELD_NAME_ROUTE_GROUPS = "routeGroups"; // System interface public static final String ACTIVITY = "android.app.Activity"; @@ -18,20 +19,24 @@ public class Constants { public static final String DOCS_PACKAGE_NAME = PACKAGE_NAME + ".docs"; public static final String GOROUTER_PACKAGE_NAME = PACKAGE_NAME + ".core.GoRouter"; public static final String I_ROUTE_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".load.IRouteModule"; + public static final String I_ROUTE_MODULE_GROUP_PACKAGE_NAME = PACKAGE_NAME + ".load.IRouteModuleGroup"; + public static final String I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD = "load"; // Log public static final String PREFIX_OF_LOGGER = PROJECT + "::Compiler "; - public static final String NO_MODULE_NAME_TIPS = "These no module name, at 'build.gradle', like :\n" + - "android {\n" + - " defaultConfig {\n" + - " ...\n" + - " javaCompileOptions {\n" + - " annotationProcessorOptions {\n" + - " arguments = [GOROUTER_MODULE_NAME: project.getName()]\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n"; + public static final String NO_MODULE_NAME_TIPS = """ + These no module name, at 'build.gradle', like : + android { + defaultConfig { + ... + javaCompileOptions { + annotationProcessorOptions { + arguments = [GOROUTER_MODULE_NAME: project.getName()] + } + } + } + } + """; // Options of processor public static final String KEY_MODULE_NAME = "GOROUTER_MODULE_NAME"; diff --git a/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java b/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java deleted file mode 100644 index 08a75e5..0000000 --- a/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.wyjson.module_main.activity; - -import android.util.ArrayMap; - -import com.wyjson.router.load.IRouteModuleGroup; - -import java.util.Map; - -public class RouteGroupTest { - - public void load() { - //... - loadRouteGroup(); - } - - Map routeGroups = new ArrayMap<>(); - - private void loadRouteGroup() { - routeGroups.put("my", new IRouteModuleGroup() { - @Override - public void load() { - // loadRouteForMyGroup() - } - }); - routeGroups.put("user", new IRouteModuleGroup() { - @Override - public void load() { - // loadRouteForUserGroup() - } - }); - } - - private void loadRouteForMyGroup() { - // commit() - } - - private void loadRouteForUserGroup() { - // commit() - } -} From 94206f2479c9197d3db92e44ba8039fd3c88860c Mon Sep 17 00:00:00 2001 From: Wyjson Date: Thu, 9 Nov 2023 19:10:19 +0800 Subject: [PATCH 05/28] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=88=86=E7=BB=84compi?= =?UTF-8?q?ler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GenerateModuleRouteProcessor.java | 271 +++++++++++------- .../router/compiler/utils/Constants.java | 27 +- .../module_main/activity/RouteGroupTest.java | 40 --- 3 files changed, 187 insertions(+), 151 deletions(-) delete mode 100644 module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index 29db760..6874303 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -9,16 +9,20 @@ import static com.wyjson.router.compiler.utils.Constants.CHAR_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.DOUBEL_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.DOUBEL_PRIMITIVE; +import static com.wyjson.router.compiler.utils.Constants.FIELD_NAME_ROUTE_GROUPS; import static com.wyjson.router.compiler.utils.Constants.FLOAT_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.FLOAT_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.FRAGMENT; import static com.wyjson.router.compiler.utils.Constants.GOROUTER_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.INTEGER_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.INTEGER_PRIMITIVE; +import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD; +import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_GROUP_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.LONG_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.LONG_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_GROUP; import static com.wyjson.router.compiler.utils.Constants.MODULE_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.PARCELABLE_PACKAGE; @@ -36,8 +40,10 @@ import com.google.auto.service.AutoService; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; import com.wyjson.router.annotation.Interceptor; import com.wyjson.router.annotation.Param; @@ -49,13 +55,18 @@ import org.apache.commons.lang3.StringUtils; import java.io.IOException; +import java.util.Comparator; +import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; +import java.util.TreeSet; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; @@ -65,8 +76,12 @@ public class GenerateModuleRouteProcessor extends BaseProcessor { TypeElement mGoRouter; TypeElement mIRouteModule; + TypeElement mIRouteModuleGroup; TypeMirror serializableType; TypeMirror parcelableType; + TypeMirror activityType; + TypeMirror fragmentType; + private final Map> routeGroupMap = new HashMap<>(); @Override public Set getSupportedAnnotationTypes() { @@ -84,8 +99,11 @@ public synchronized void init(ProcessingEnvironment processingEnv) { logger.info(moduleName + " >>> GenerateModuleRouteProcessor init. <<<"); mGoRouter = elementUtils.getTypeElement(GOROUTER_PACKAGE_NAME); mIRouteModule = elementUtils.getTypeElement(I_ROUTE_MODULE_PACKAGE_NAME); + mIRouteModuleGroup = elementUtils.getTypeElement(I_ROUTE_MODULE_GROUP_PACKAGE_NAME); serializableType = elementUtils.getTypeElement(SERIALIZABLE_PACKAGE).asType(); parcelableType = elementUtils.getTypeElement(PARCELABLE_PACKAGE).asType(); + activityType = elementUtils.getTypeElement(ACTIVITY).asType(); + fragmentType = elementUtils.getTypeElement(FRAGMENT).asType(); } @Override @@ -95,28 +113,27 @@ public boolean process(Set set, RoundEnvironment roundEnv DocumentUtils.createDoc(mFiler, moduleName, logger, isGenerateDoc); - MethodSpec.Builder loadInto = MethodSpec.methodBuilder(METHOD_NAME_LOAD) + String className = generateClassName + SEPARATOR + PROJECT; + TypeSpec.Builder thisClass = TypeSpec.classBuilder(className) + .addModifiers(PUBLIC) + .addSuperinterface(ClassName.get(mIRouteModule)) + .addJavadoc(WARNING_TIPS); + + MethodSpec.Builder loadIntoMethod = MethodSpec.methodBuilder(METHOD_NAME_LOAD) .addModifiers(PUBLIC) .addAnnotation(Override.class); - loadInto.addJavadoc("load the $S route", moduleName); + loadIntoMethod.addJavadoc("load the $S route", moduleName); - addService(roundEnvironment, loadInto); - addInterceptor(roundEnvironment, loadInto); - addRoute(roundEnvironment, loadInto); - LinkedHashSet routeGroupMethods = addRouteGroup(roundEnvironment, loadInto); + addService(roundEnvironment, loadIntoMethod); + addInterceptor(roundEnvironment, loadIntoMethod); + LinkedHashSet routeGroupMethods = addRouteGroup(roundEnvironment, thisClass, loadIntoMethod); - String className = generateClassName + SEPARATOR + PROJECT; + thisClass.addMethod(loadIntoMethod.build()).addMethods(routeGroupMethods); try { - JavaFile.builder(MODULE_PACKAGE_NAME, - TypeSpec.classBuilder(className) - .addModifiers(PUBLIC) - .addSuperinterface(ClassName.get(mIRouteModule)) - .addJavadoc(WARNING_TIPS) - .addMethod(loadInto.build()) - .addMethods(routeGroupMethods) - .build() - ).indent(" ").build().writeTo(mFiler); - + JavaFile.builder(MODULE_PACKAGE_NAME, thisClass.build()) + .indent(" ") + .build() + .writeTo(mFiler); logger.info(moduleName + " >>> GenerateModuleRouteProcessor over. <<<"); } catch (IOException e) { logger.error(moduleName + " Failed to generate [" + className + "] class!"); @@ -127,124 +144,178 @@ public boolean process(Set set, RoundEnvironment roundEnv return true; } - private void addService(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { + private void addService(RoundEnvironment roundEnvironment, MethodSpec.Builder loadIntoMethod) { Set elements = roundEnvironment.getElementsAnnotatedWith(Service.class); if (CollectionUtils.isEmpty(elements)) return; logger.info(moduleName + " >>> Found Service, size is " + elements.size() + " <<<"); - loadInto.addCode("// add Service\n"); + loadIntoMethod.addCode("// add Service\n"); for (Element element : elements) { Service service = element.getAnnotation(Service.class); - loadInto.addStatement("$T.getInstance().addService($T.class)", mGoRouter, element); + loadIntoMethod.addStatement("$T.getInstance().addService($T.class)", mGoRouter, element); DocumentUtils.addServiceDoc(moduleName, logger, element, service); } } - private void addInterceptor(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { + private void addInterceptor(RoundEnvironment roundEnvironment, MethodSpec.Builder loadIntoMethod) { Set elements = roundEnvironment.getElementsAnnotatedWith(Interceptor.class); if (CollectionUtils.isEmpty(elements)) return; logger.info(moduleName + " >>> Found Interceptor, size is " + elements.size() + " <<<"); - loadInto.addCode("// add Interceptor\n"); + loadIntoMethod.addCode("// add Interceptor\n"); for (Element element : elements) { Interceptor interceptor = element.getAnnotation(Interceptor.class); - loadInto.addStatement("$T.getInstance().addInterceptor(" + interceptor.priority() + ", $T.class)", mGoRouter, element); + loadIntoMethod.addStatement("$T.getInstance().addInterceptor(" + interceptor.priority() + ", $T.class)", mGoRouter, element); DocumentUtils.addInterceptorDoc(moduleName, logger, element, interceptor); } } - private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { - LinkedHashSet methodSpecs = new LinkedHashSet<>(); - MethodSpec.Builder loadRouteGroup = MethodSpec.methodBuilder(METHOD_NAME_LOAD_ROUTE_GROUP).addModifiers(PRIVATE); - loadRouteGroup.addJavadoc("load route group"); - - loadInto.addStatement("$N()", loadRouteGroup.build()); - methodSpecs.add(loadRouteGroup.build()); - return methodSpecs; - } + private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironment, TypeSpec.Builder thisClass, MethodSpec.Builder loadIntoMethod) { + LinkedHashSet routeGroupMethods = new LinkedHashSet<>(); - private void addRoute(RoundEnvironment roundEnvironment, MethodSpec.Builder loadInto) { Set elements = roundEnvironment.getElementsAnnotatedWith(Route.class); if (CollectionUtils.isEmpty(elements)) - return; + return routeGroupMethods; logger.info(moduleName + " >>> Found Route, size is " + elements.size() + " <<<"); - TypeMirror typeActivity = elementUtils.getTypeElement(ACTIVITY).asType(); - TypeMirror typeFragment = elementUtils.getTypeElement(FRAGMENT).asType(); + FieldSpec routeGroupsField = FieldSpec.builder( + ParameterizedTypeName.get( + ClassName.get(Map.class), + ClassName.get(String.class), + ClassName.get(mIRouteModuleGroup) + ), + FIELD_NAME_ROUTE_GROUPS, + Modifier.PRIVATE, + Modifier.FINAL + ) + .initializer("new $T()", ClassName.get(HashMap.class)) + .build(); + thisClass.addField(routeGroupsField); + + MethodSpec.Builder loadRouteGroupMethod = MethodSpec.methodBuilder(METHOD_NAME_LOAD_ROUTE_GROUP).addModifiers(PRIVATE); + loadRouteGroupMethod.addJavadoc("load route group"); + loadRouteGroupMethod.addStatement("$N.clear()", routeGroupsField); + + saveRouteGroup(elements); + + for (Map.Entry> entry : routeGroupMap.entrySet()) { + String groupName = entry.getKey(); + // 首字母大写 + String groupNameToUpperCase = groupName.substring(0, 1).toUpperCase() + groupName.substring(1); + String methodName = String.format(METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP, groupNameToUpperCase); + MethodSpec.Builder loadRouteForXGroupMethod = MethodSpec.methodBuilder(methodName).addModifiers(PRIVATE); + loadRouteForXGroupMethod.addJavadoc("\"" + groupName + "\" route group"); + for (Element element : entry.getValue()) { + addRoute(element, loadRouteForXGroupMethod); + } + MethodSpec loadRouteForXGroupMethodBuild = loadRouteForXGroupMethod.build(); + routeGroupMethods.add(loadRouteForXGroupMethodBuild); + + // 把每个路由分组方法汇总到loadRouteGroup方法中 + CodeBlock.Builder iRouteModuleGroupCode = CodeBlock.builder(); + iRouteModuleGroupCode.beginControlFlow("new $N()", ClassName.get(mIRouteModuleGroup).simpleName()); + iRouteModuleGroupCode.indent().add("@Override\n"); + iRouteModuleGroupCode.beginControlFlow("public void $N()", I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD); + iRouteModuleGroupCode.indent().addStatement("$N()", loadRouteForXGroupMethodBuild.name); + iRouteModuleGroupCode.unindent().endControlFlow(); + iRouteModuleGroupCode.add("}"); + + CodeBlock.Builder routeGroupPutCode = CodeBlock.builder(); + routeGroupPutCode.add("$N.put($S, $N)", routeGroupsField, groupName, iRouteModuleGroupCode.build().toString()); + + loadRouteGroupMethod.addStatement(routeGroupPutCode.build()); + } + + loadIntoMethod.addCode("// call load route group\n"); + loadIntoMethod.addStatement("$N()", loadRouteGroupMethod.build()); + routeGroupMethods.add(loadRouteGroupMethod.build()); + return routeGroupMethods; + } - loadInto.addCode("// add Route\n"); + private void saveRouteGroup(Set elements) { + routeGroupMap.clear(); for (Element element : elements) { Route route = element.getAnnotation(Route.class); - TypeMirror tm = element.asType(); - -// String typeDoc; -// String type; -// // handle type -// if (types.isSubtype(tm, typeActivity)) { -// typeDoc = "Activity"; -// type = ".commitActivity($T.class)"; -// } else if (types.isSubtype(tm, typeFragment)) { -// typeDoc = "Fragment"; -// type = ".commitFragment($T.class)"; -// } else { -// throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') is marked on unsupported class, look at [" + tm.toString() + "]."); -// } -// -// String tag = route.tag() == 0 ? "" : ".putTag(" + route.tag() + ")"; -// -// // Get all fields annotation by @Param -// String param = ""; -// try { -// param = handleParam(new StringBuilder(), element); -// } catch (Exception e) { -// throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); -// } -// loadInto.addStatement("$T.getInstance().build($S)" + tag + param + type, mGoRouter, route.path(), element); -// DocumentUtils.addRoute(moduleName, logger, element, route, typeDoc); - - CodeBlock.Builder unifyCode = CodeBlock.builder(); - // GoRouter.getInstance().build(xxx) - CodeBlock.Builder buildCode = CodeBlock.builder().add("$T.getInstance().build($S)", mGoRouter, route.path()); - unifyCode.add(buildCode.build()); - - // .putTag(x) - CodeBlock.Builder tagCode = CodeBlock.builder(); - if (route.tag() != 0) { - tagCode.add(".putTag($L)", route.tag()); - } - unifyCode.add(tagCode.build()); - - // .putInt(x).putString(x) ... - // Get all fields annotation by @Param - CodeBlock.Builder paramCode = CodeBlock.builder(); - try { - paramCode = handleParam(paramCode, element); - } catch (Exception e) { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); - } - unifyCode.add(paramCode.build()); - - // .commitXXX(x) - String typeDoc; - CodeBlock.Builder typeCode = CodeBlock.builder(); - if (types.isSubtype(tm, typeActivity)) { - typeDoc = "Activity"; - typeCode.add(".commitActivity($T.class)", element); - } else if (types.isSubtype(tm, typeFragment)) { - typeDoc = "Fragment"; - typeCode.add(".commitFragment($T.class)", element); + String group = extractRouteGroup(route.path()); + Set routeSet = routeGroupMap.get(group); + if (CollectionUtils.isEmpty(routeSet)) { + Set sortRouteSet = new TreeSet<>(new Comparator() { + @Override + public int compare(Element r1, Element r2) { + String r1Path = r1.getAnnotation(Route.class).path(); + String r2Path = r2.getAnnotation(Route.class).path(); + return r1Path.compareTo(r2Path); + } + }); + sortRouteSet.add(element); + routeGroupMap.put(group, sortRouteSet); } else { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') is marked on unsupported class, look at [" + tm.toString() + "]."); + routeSet.add(element); } - unifyCode.add(typeCode.build()); + } + } - loadInto.addStatement(unifyCode.build()); - DocumentUtils.addRouteDoc(moduleName, logger, element, route, typeDoc); + private String extractRouteGroup(String path) { + if (StringUtils.isEmpty(path) || !path.startsWith("/")) { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The path[" + path + "] must be start with '/' and not empty!"); + } + try { + String group = path.substring(1, path.indexOf("/", 1)); + if (StringUtils.isEmpty(group)) { + throw new RuntimeException("The group is empty!"); + } + return group; + } catch (Exception e) { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Failed to extract the path[" + path + "] group. The path must have at least two levels '/xx/xx' and start with '/'! " + e.getMessage()); } } + private void addRoute(Element element, MethodSpec.Builder loadRouteGroupMethod) { + Route route = element.getAnnotation(Route.class); + TypeMirror tm = element.asType(); + + CodeBlock.Builder unifyCode = CodeBlock.builder(); + // GoRouter.getInstance().build(xxx) + CodeBlock.Builder buildCode = CodeBlock.builder().add("$T.getInstance().build($S)", mGoRouter, route.path()); + unifyCode.add(buildCode.build()); + + // .putTag(x) + CodeBlock.Builder tagCode = CodeBlock.builder(); + if (route.tag() != 0) { + tagCode.add(".putTag($L)", route.tag()); + } + unifyCode.add(tagCode.build()); + + // .putInt(x).putString(x) ... + // Get all fields annotation by @Param + CodeBlock.Builder paramCode = CodeBlock.builder(); + try { + paramCode = handleParam(paramCode, element); + } catch (Exception e) { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') under " + e.getMessage()); + } + unifyCode.add(paramCode.build()); + + // .commitXXX(x) + String typeDoc; + CodeBlock.Builder typeCode = CodeBlock.builder(); + if (types.isSubtype(tm, activityType)) { + typeDoc = "Activity"; + typeCode.add(".commitActivity($T.class)", element); + } else if (types.isSubtype(tm, fragmentType)) { + typeDoc = "Fragment"; + typeCode.add(".commitFragment($T.class)", element); + } else { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The @Route(path='" + route.path() + "') is marked on unsupported class, look at [" + tm.toString() + "]."); + } + unifyCode.add(typeCode.build()); + + loadRouteGroupMethod.addStatement(unifyCode.build()); + DocumentUtils.addRouteDoc(moduleName, logger, element, route, typeDoc); + } + private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element element) { CodeBlock.Builder tempParamCode = CodeBlock.builder(); for (Element field : element.getEnclosedElements()) { @@ -282,7 +353,7 @@ private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element eleme if (!StringUtils.isEmpty(param.name())) { tempParamCode.add(".$N($S, $S, $L)", paramType, key, param.name(), param.required()); } else { - tempParamCode.add(".$N($S, $L, $L)", paramType, key, "null", param.required()); + tempParamCode.add(".$N($S, null, $L)", paramType, key, param.required()); } } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java index 36b8667..49ea391 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java @@ -8,6 +8,7 @@ public class Constants { public static final String METHOD_NAME_LOAD = "load"; public static final String METHOD_NAME_LOAD_ROUTE_GROUP = "loadRouteGroup"; public static final String METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP = "loadRouteFor%sGroup"; + public static final String FIELD_NAME_ROUTE_GROUPS = "routeGroups"; // System interface public static final String ACTIVITY = "android.app.Activity"; @@ -18,20 +19,24 @@ public class Constants { public static final String DOCS_PACKAGE_NAME = PACKAGE_NAME + ".docs"; public static final String GOROUTER_PACKAGE_NAME = PACKAGE_NAME + ".core.GoRouter"; public static final String I_ROUTE_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".load.IRouteModule"; + public static final String I_ROUTE_MODULE_GROUP_PACKAGE_NAME = PACKAGE_NAME + ".load.IRouteModuleGroup"; + public static final String I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD = "load"; // Log public static final String PREFIX_OF_LOGGER = PROJECT + "::Compiler "; - public static final String NO_MODULE_NAME_TIPS = "These no module name, at 'build.gradle', like :\n" + - "android {\n" + - " defaultConfig {\n" + - " ...\n" + - " javaCompileOptions {\n" + - " annotationProcessorOptions {\n" + - " arguments = [GOROUTER_MODULE_NAME: project.getName()]\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n"; + public static final String NO_MODULE_NAME_TIPS = """ + These no module name, at 'build.gradle', like : + android { + defaultConfig { + ... + javaCompileOptions { + annotationProcessorOptions { + arguments = [GOROUTER_MODULE_NAME: project.getName()] + } + } + } + } + """; // Options of processor public static final String KEY_MODULE_NAME = "GOROUTER_MODULE_NAME"; diff --git a/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java b/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java deleted file mode 100644 index 08a75e5..0000000 --- a/module_main/src/main/java/com/wyjson/module_main/activity/RouteGroupTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.wyjson.module_main.activity; - -import android.util.ArrayMap; - -import com.wyjson.router.load.IRouteModuleGroup; - -import java.util.Map; - -public class RouteGroupTest { - - public void load() { - //... - loadRouteGroup(); - } - - Map routeGroups = new ArrayMap<>(); - - private void loadRouteGroup() { - routeGroups.put("my", new IRouteModuleGroup() { - @Override - public void load() { - // loadRouteForMyGroup() - } - }); - routeGroups.put("user", new IRouteModuleGroup() { - @Override - public void load() { - // loadRouteForUserGroup() - } - }); - } - - private void loadRouteForMyGroup() { - // commit() - } - - private void loadRouteForUserGroup() { - // commit() - } -} From 6204ce97164a04e6ebf012efca83ee16b82c6427 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Fri, 10 Nov 2023 11:05:48 +0800 Subject: [PATCH 06/28] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E4=BC=9A=E5=87=BA=E7=8E=B0=E7=A9=BA=E6=8C=87=E9=92=88=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/wyjson/router/card/Card.java | 5 ++ .../java/com/wyjson/router/card/CardMeta.java | 30 ++++++++++- .../java/com/wyjson/router/core/GoRouter.java | 6 +-- .../com/wyjson/router/route/RouteHelper.java | 2 +- .../GenerateModuleRouteProcessor.java | 53 ++++++++++++++----- 5 files changed, 76 insertions(+), 20 deletions(-) diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java b/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java index 6b4f432..93cd189 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java @@ -14,7 +14,9 @@ import com.wyjson.router.callback.GoCallback; import com.wyjson.router.core.GoRouter; import com.wyjson.router.enums.RouteType; +import com.wyjson.router.exception.RouterException; import com.wyjson.router.route.RouteHelper; +import com.wyjson.router.utils.TextUtils; import java.io.Serializable; import java.util.ArrayList; @@ -36,6 +38,9 @@ public final class Card extends CardMeta { private int timeout = 300;// go() timeout, TimeUnit.Second public void setUri(Uri uri) { + if (uri == null || TextUtils.isEmpty(uri.toString()) || TextUtils.isEmpty(uri.getPath())) { + throw new RouterException("uri Parameter is invalid!"); + } this.uri = uri; setPath(uri.getPath()); } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java b/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java index f5d7674..8ccffca 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java @@ -6,6 +6,7 @@ import com.wyjson.router.core.GoRouter; import com.wyjson.router.enums.ParamType; import com.wyjson.router.enums.RouteType; +import com.wyjson.router.exception.RouterException; import com.wyjson.router.param.ParamMeta; import com.wyjson.router.route.RouteHelper; import com.wyjson.router.utils.TextUtils; @@ -15,6 +16,7 @@ public class CardMeta { private String path; + private String group; private RouteType type; private Class pathClass; private int tag;// 额外的标记 @@ -24,7 +26,7 @@ protected CardMeta() { } public CardMeta(String path, RouteType type, Class pathClass, int tag, Map paramsType) { - this.path = path; + setPath(path); this.type = type; this.pathClass = pathClass; this.tag = tag; @@ -37,9 +39,35 @@ public String getPath() { } public void setPath(@NonNull String path) { + if (TextUtils.isEmpty(path)) { + throw new RouterException("path Parameter is invalid!"); + } this.path = path; + this.group = extractGroup(path); + } + + public String getGroup() { + return group; + } + + private String extractGroup(String path) { + if (TextUtils.isEmpty(path) || !path.startsWith("/")) { + throw new RouterException("Extract the path[" + path + "] group failed, the path must be start with '/' and contain more than 2 '/'!"); + } + + try { + String group = path.substring(1, path.indexOf("/", 1)); + if (TextUtils.isEmpty(group)) { + throw new RouterException("Extract the path[" + path + "] group failed! There's nothing between 2 '/'!"); + } else { + return group; + } + } catch (Exception e) { + throw new RouterException("Failed to extract path[" + path + "] group! " + e.getMessage()); + } } + public RouteType getType() { return type; } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/GoRouter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/GoRouter.java index 68067b1..9967b58 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/GoRouter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/GoRouter.java @@ -167,9 +167,6 @@ public Card build(String path, Bundle bundle) { } public Card build(Uri uri) { - if (uri == null || TextUtils.isEmpty(uri.toString())) { - throw new RouterException("uri Parameter is invalid!"); - } return new Card(uri); } @@ -289,7 +286,8 @@ public Object go(Context context, Card card, int requestCode, GoCallback callbac } else { logger.warning(null, "[go] This [PretreatmentService] was not found!"); } - CardMeta cardMeta = RouteHelper.getInstance().getCardMeta(card); + + CardMeta cardMeta = card.getCardMeta(); if (cardMeta != null) { card.setCardMeta(cardMeta.getType(), cardMeta.getPathClass(), cardMeta.getTag()); diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/route/RouteHelper.java b/GoRouter-Api/src/main/java/com/wyjson/router/route/RouteHelper.java index 510aef0..1db2752 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/route/RouteHelper.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/route/RouteHelper.java @@ -32,7 +32,7 @@ public Map getRoutes() { @Nullable public CardMeta getCardMeta(Card card) { - CardMeta cardMeta = RouteHelper.getInstance().getRoutes().get(card.getPath()); + CardMeta cardMeta = routes.get(card.getPath()); if (cardMeta != null) { GoRouter.logger.info(null, "[getCardMeta] " + cardMeta); } else { diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index 6874303..3ee8108 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -259,16 +259,16 @@ public int compare(Element r1, Element r2) { private String extractRouteGroup(String path) { if (StringUtils.isEmpty(path) || !path.startsWith("/")) { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " The path[" + path + "] must be start with '/' and not empty!"); + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Extract the path[" + path + "] group failed, Extract the default group failed, the path must be start with '/' and contain more than 2 '/'!"); } try { String group = path.substring(1, path.indexOf("/", 1)); if (StringUtils.isEmpty(group)) { - throw new RuntimeException("The group is empty!"); + throw new RuntimeException("Extract the default group failed! There's nothing between 2 '/'!"); } return group; } catch (Exception e) { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Failed to extract the path[" + path + "] group. The path must have at least two levels '/xx/xx' and start with '/'! " + e.getMessage()); + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Failed to extract path[" + path + "] group! " + e.getMessage()); } } @@ -327,16 +327,42 @@ private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element eleme String typeStr = typeMirror.toString(); String paramType; switch (typeStr) { - case BYTE_PACKAGE, BYTE_PRIMITIVE -> paramType = "putByte"; - case SHORT_PACKAGE, SHORT_PRIMITIVE -> paramType = "putShort"; - case INTEGER_PACKAGE, INTEGER_PRIMITIVE -> paramType = "putInt"; - case LONG_PACKAGE, LONG_PRIMITIVE -> paramType = "putLong"; - case FLOAT_PACKAGE, FLOAT_PRIMITIVE -> paramType = "putFloat"; - case DOUBEL_PACKAGE, DOUBEL_PRIMITIVE -> paramType = "putDouble"; - case BOOLEAN_PACKAGE, BOOLEAN_PRIMITIVE -> paramType = "putBoolean"; - case CHAR_PACKAGE, CHAR_PRIMITIVE -> paramType = "putChar"; - case STRING_PACKAGE -> paramType = "putString"; - default -> { + case BYTE_PACKAGE: + case BYTE_PRIMITIVE: + paramType = "putByte"; + break; + case SHORT_PACKAGE: + case SHORT_PRIMITIVE: + paramType = "putShort"; + break; + case INTEGER_PACKAGE: + case INTEGER_PRIMITIVE: + paramType = "putInt"; + break; + case LONG_PACKAGE: + case LONG_PRIMITIVE: + paramType = "putLong"; + break; + case FLOAT_PACKAGE: + case FLOAT_PRIMITIVE: + paramType = "putFloat"; + break; + case DOUBEL_PACKAGE: + case DOUBEL_PRIMITIVE: + paramType = "putDouble"; + break; + case BOOLEAN_PACKAGE: + case BOOLEAN_PRIMITIVE: + paramType = "putBoolean"; + break; + case CHAR_PACKAGE: + case CHAR_PRIMITIVE: + paramType = "putChar"; + break; + case STRING_PACKAGE: + paramType = "putString"; + break; + default: if (types.isSubtype(typeMirror, parcelableType)) { paramType = "putParcelable"; } else if (types.isSubtype(typeMirror, serializableType)) { @@ -344,7 +370,6 @@ private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element eleme } else { throw new RuntimeException("@Param(type='" + typeMirror + "') is marked as an unsupported type"); } - } } if (StringUtils.isEmpty(param.name()) && !param.required()) { From 55acca4cf8bb8639e2710309d673159b4119b946 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Fri, 10 Nov 2023 11:48:56 +0800 Subject: [PATCH 07/28] optimize code --- .../router/compiler/processor/GenerateModuleRouteProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index 3ee8108..c334e19 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -190,7 +190,7 @@ private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironmen Modifier.PRIVATE, Modifier.FINAL ) - .initializer("new $T()", ClassName.get(HashMap.class)) + .initializer("new $T<>()", ClassName.get(HashMap.class)) .build(); thisClass.addField(routeGroupsField); From 7b7f42199a81ba8004ab0b81f48ad0099fce1add Mon Sep 17 00:00:00 2001 From: Wyjson Date: Fri, 10 Nov 2023 18:25:23 +0800 Subject: [PATCH 08/28] =?UTF-8?q?1.=E6=8C=89=E9=9C=80=E5=88=86=E7=BB=84?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E8=B7=AF=E7=94=B1=202.=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=95=B4=E4=BD=93=E5=8C=85=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GoRouter-Api/consumer-rules.pro | 2 +- .../main/java/com/wyjson/router/GoRouter.java | 346 +++++++++++++ .../wyjson/router/callback/GoCallback.java | 2 +- .../InterceptorCallback.java | 4 +- .../callback/{ => impl}/GoCallbackImpl.java | 5 +- .../java/com/wyjson/router/core/GoRouter.java | 472 ------------------ .../impl => core}/InterceptorServiceImpl.java | 21 +- .../wyjson/router/core/LogisticsCenter.java | 315 ++++++++++++ .../RouteModuleLoadCenter.java} | 32 +- .../com/wyjson/router/core/Warehouse.java | 22 + .../core/interfaces/IInterceptorService.java | 9 + .../exception/NoFoundRouteException.java | 9 + .../router/interceptor/InterceptorHelper.java | 66 --- .../service/InterceptorService.java | 9 - ...gradeService.java => IDegradeService.java} | 4 +- .../router/interfaces/IInterceptor.java | 4 +- ...Service.java => IPretreatmentService.java} | 4 +- .../wyjson/router/{card => model}/Card.java | 15 +- .../router/{card => model}/CardMeta.java | 13 +- .../router/{param => model}/ParamMeta.java | 4 +- .../{service => model}/ServiceMeta.java | 2 +- .../interfaces}/IRouteModule.java | 2 +- .../interfaces}/IRouteModuleGroup.java | 2 +- .../com/wyjson/router/route/RouteHelper.java | 64 --- .../wyjson/router/service/ServiceHelper.java | 73 --- .../router/thread/DefaultPoolExecutor.java | 2 +- .../router/thread/DefaultThreadFactory.java | 2 +- .../com/wyjson/router/utils/ClassUtils.java | 10 +- .../InterceptorTreeMap.java | 4 +- .../com/wyjson/router/utils/PackageUtils.java | 4 +- .../compiler/processor/BaseProcessor.java | 2 +- .../GenerateModuleRouteProcessor.java | 78 +-- .../router/compiler/utils/Constants.java | 21 +- .../core/AssembleModuleRouteTask.kt | 8 +- .../router/gradle_plugin/utils/Constants.kt | 6 +- README.md | 24 +- .../com/wyjson/go_router/MyApplication.java | 2 +- .../route/service/DegradeServiceImpl.java | 6 +- .../service/PretreatmentServiceImpl.java | 6 +- .../module_main/activity/MainActivity.java | 4 +- .../module_main/activity/SplashActivity.java | 6 +- .../module_user/activity/ParamActivity.java | 2 +- .../module_user/fragment/ParamFragment.java | 2 +- .../AuthenticationInterceptor.java | 4 +- .../route/interceptor/SignInInterceptor.java | 7 +- settings.gradle | 2 +- 46 files changed, 872 insertions(+), 831 deletions(-) create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java rename GoRouter-Api/src/main/java/com/wyjson/router/{interceptor => callback}/InterceptorCallback.java (70%) rename GoRouter-Api/src/main/java/com/wyjson/router/callback/{ => impl}/GoCallbackImpl.java (75%) delete mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/core/GoRouter.java rename GoRouter-Api/src/main/java/com/wyjson/router/{interceptor/service/impl => core}/InterceptorServiceImpl.java (79%) create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java rename GoRouter-Api/src/main/java/com/wyjson/router/{load/RouteModuleLoadUtils.java => core/RouteModuleLoadCenter.java} (82%) create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/core/interfaces/IInterceptorService.java create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/exception/NoFoundRouteException.java delete mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorHelper.java delete mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/interceptor/service/InterceptorService.java rename GoRouter-Api/src/main/java/com/wyjson/router/interfaces/{DegradeService.java => IDegradeService.java} (69%) rename GoRouter-Api/src/main/java/com/wyjson/router/interfaces/{PretreatmentService.java => IPretreatmentService.java} (78%) rename GoRouter-Api/src/main/java/com/wyjson/router/{card => model}/Card.java (95%) rename GoRouter-Api/src/main/java/com/wyjson/router/{card => model}/CardMeta.java (93%) rename GoRouter-Api/src/main/java/com/wyjson/router/{param => model}/ParamMeta.java (93%) rename GoRouter-Api/src/main/java/com/wyjson/router/{service => model}/ServiceMeta.java (93%) rename GoRouter-Api/src/main/java/com/wyjson/router/{load => module/interfaces}/IRouteModule.java (79%) rename GoRouter-Api/src/main/java/com/wyjson/router/{load => module/interfaces}/IRouteModuleGroup.java (81%) delete mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/route/RouteHelper.java delete mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/service/ServiceHelper.java rename GoRouter-Api/src/main/java/com/wyjson/router/{interceptor => utils}/InterceptorTreeMap.java (94%) diff --git a/GoRouter-Api/consumer-rules.pro b/GoRouter-Api/consumer-rules.pro index a9a676f..739a488 100644 --- a/GoRouter-Api/consumer-rules.pro +++ b/GoRouter-Api/consumer-rules.pro @@ -5,5 +5,5 @@ @com.wyjson.router.annotation.Param ; } # 自动注册模块路由加载类不混淆 --keep class * implements com.wyjson.router.load.IRouteModule +-keep class * implements com.wyjson.router.module.interfaces.IRouteModule # # ########## GoRouter # end ########## \ No newline at end of file diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java new file mode 100644 index 0000000..eed8ba4 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java @@ -0,0 +1,346 @@ +package com.wyjson.router; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import androidx.fragment.app.Fragment; + +import com.wyjson.router.callback.GoCallback; +import com.wyjson.router.callback.InterceptorCallback; +import com.wyjson.router.core.InterceptorServiceImpl; +import com.wyjson.router.core.LogisticsCenter; +import com.wyjson.router.core.RouteModuleLoadCenter; +import com.wyjson.router.core.interfaces.IInterceptorService; +import com.wyjson.router.exception.NoFoundRouteException; +import com.wyjson.router.exception.RouterException; +import com.wyjson.router.interfaces.IDegradeService; +import com.wyjson.router.interfaces.IInterceptor; +import com.wyjson.router.interfaces.IPretreatmentService; +import com.wyjson.router.interfaces.IService; +import com.wyjson.router.logger.DefaultLogger; +import com.wyjson.router.logger.ILogger; +import com.wyjson.router.model.Card; +import com.wyjson.router.thread.DefaultPoolExecutor; +import com.wyjson.router.utils.TextUtils; + +import java.util.concurrent.ThreadPoolExecutor; + +public final class GoRouter { + + public static final String ROUTER_CURRENT_PATH = "go_router_current_path"; + public static final String ROUTER_RAW_URI = "go_router_raw_uri"; + + private final Handler mHandler = new Handler(Looper.getMainLooper()); + private volatile static ThreadPoolExecutor executor = DefaultPoolExecutor.getInstance(); + public static ILogger logger = new DefaultLogger(); + private volatile static boolean isDebug = false; + + private GoRouter() { + LogisticsCenter.clearInterceptors(); + LogisticsCenter.addService(InterceptorServiceImpl.class); + } + + private static class InstanceHolder { + private static final GoRouter mInstance = new GoRouter(); + } + + public static GoRouter getInstance() { + return InstanceHolder.mInstance; + } + + /** + * 自动加载模块路由 + * + * @param application + */ + public static synchronized void autoLoadModuleRoute(Application application) { + logger.info(null, "[GoRouter] autoLoadModuleRoute!"); + RouteModuleLoadCenter.loadModuleRoute(application); + } + + /** + * 获取路由注册模式 + * + * @return true [GoRouter-Gradle-Plugin] ,false [scan dex file] + */ + public boolean isRouteRegisterMode() { + return RouteModuleLoadCenter.isRegisterByPlugin(); + } + + public static synchronized void openDebug() { + isDebug = true; + logger.showLog(isDebug); + logger.info(null, "[openDebug]"); + } + + public static boolean isDebug() { + return isDebug; + } + + public static synchronized void printStackTrace() { + logger.showStackTrace(true); + logger.info(null, "[printStackTrace]"); + } + + public static synchronized void setExecutor(ThreadPoolExecutor tpe) { + executor = tpe; + } + + public ThreadPoolExecutor getExecutor() { + return executor; + } + + public static void setLogger(ILogger userLogger) { + if (userLogger != null) { + logger = userLogger; + } + } + + /** + * 实现相同接口的service会被覆盖(更新) + * 调用时机可以在application或插件模块加载时 + * + * @param service 实现类.class + */ + public void addService(Class service) { + LogisticsCenter.addService(service); + } + + /** + * 获取service接口的实现 + * + * @param service 接口.class + * @param + * @return + */ + @Nullable + public T getService(Class service) { + return LogisticsCenter.getService(service); + } + + /** + * 相同优先级添加会catch + * 调用时机可以在application或插件模块加载时 + * + * @param priority + * @param interceptor + */ + public void addInterceptor(int priority, Class interceptor) { + LogisticsCenter.addInterceptor(priority, interceptor, false); + } + + /** + * 相同优先级添加会覆盖 + * 调用时机可以在application或插件模块加载时 + * + * @param priority + * @param interceptor + */ + public void setInterceptor(int priority, Class interceptor) { + LogisticsCenter.setInterceptor(priority, interceptor); + } + + private void runInMainThread(Runnable runnable) { + if (Looper.getMainLooper().getThread() != Thread.currentThread()) { + mHandler.post(runnable); + } else { + runnable.run(); + } + } + + public Card build(String path) { + return build(path, null); + } + + public Card build(String path, Bundle bundle) { + return new Card(path, bundle); + } + + public Card build(Uri uri) { + return new Card(uri); + } + + public void inject(Activity activity) { + LogisticsCenter.inject(activity, null, null); + } + + public void inject(Activity activity, Intent intent) { + LogisticsCenter.inject(activity, intent, null); + } + + public void inject(Activity activity, Bundle bundle) { + LogisticsCenter.inject(activity, null, bundle); + } + + public void inject(Fragment fragment) { + LogisticsCenter.inject(fragment, null, null); + } + + public void inject(Fragment fragment, Intent intent) { + LogisticsCenter.inject(fragment, intent, null); + } + + public void inject(Fragment fragment, Bundle bundle) { + LogisticsCenter.inject(fragment, null, bundle); + } + + + @Nullable + public Object go(Context context, Card card, int requestCode, GoCallback callback) { + card.setContext(context); + card.setInterceptorException(null); + card.withString(GoRouter.ROUTER_CURRENT_PATH, card.getPath()); + + logger.debug(null, "[go] " + card); + IPretreatmentService pretreatmentService = getService(IPretreatmentService.class); + if (pretreatmentService != null) { + if (!pretreatmentService.onPretreatment(context, card)) { + // 预处理失败,导航取消 + logger.debug(null, "[go] PretreatmentService Failure!"); + return null; + } + } else { + logger.warning(null, "[go] This [PretreatmentService] was not found!"); + } + + try { + LogisticsCenter.assembleRouteCard(card); + } catch (NoFoundRouteException e) { + logger.warning(null, e.getMessage()); + + if (isDebug()) { + runInMainThread(() -> Toast.makeText(context, "There's no route matched!\n" + + " Path = [" + card.getPath() + "]\n" + + " Group = [" + card.getGroup() + "]", Toast.LENGTH_LONG).show()); + } + + onLost(context, card, callback); + return null; + } + + runInMainThread(() -> { + logger.debug(null, "[go] [onFound] " + card); + if (callback != null) { + callback.onFound(card); + } + }); + + switch (card.getType()) { + case ACTIVITY: + IInterceptorService interceptorService = getService(IInterceptorService.class); + if (interceptorService != null && !card.isGreenChannel()) { + interceptorService.doInterceptions(card, new InterceptorCallback() { + @Override + public void onContinue(Card card) { + goActivity(context, card, requestCode, callback); + } + + @Override + public void onInterrupt(Card card, @NonNull Throwable exception) { + runInMainThread(() -> { + if (callback != null) { + callback.onInterrupt(card, exception); + } + }); + } + }); + } else { + goActivity(context, card, requestCode, callback); + } + break; + case FRAGMENT: + return goFragment(card, callback); + } + return null; + } + + private void onLost(Context context, Card card, GoCallback callback) { + runInMainThread(() -> { + logger.error(null, "[onLost] There is no route. path[" + card.getPath() + "]"); + if (callback != null) { + callback.onLost(card); + } else { + IDegradeService degradeService = getService(IDegradeService.class); + if (degradeService != null) { + degradeService.onLost(context, card); + } else { + logger.warning(null, "[onLost] This [DegradeService] was not found!"); + } + } + }); + } + + @SuppressLint("WrongConstant") + private void goActivity(Context context, Card card, int requestCode, GoCallback callback) { + Intent intent = new Intent(context, card.getPathClass()); + + intent.putExtras(card.getExtras()); + + int flags = card.getFlags(); + if (0 != flags) { + intent.setFlags(flags); + } + + if (!(context instanceof Activity)) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } + + String action = card.getAction(); + if (!TextUtils.isEmpty(action)) { + intent.setAction(action); + } + + runInMainThread(() -> { + if (requestCode >= 0) { + if (context instanceof Activity) { + ActivityCompat.startActivityForResult((Activity) context, intent, requestCode, card.getOptionsBundle()); + } else { + throw new RouterException("Must use [go(activity, ...)] to support [startActivityForResult]!"); + } + } else { + ActivityCompat.startActivity(context, intent, card.getOptionsBundle()); + } + + if ((-1 != card.getEnterAnim() && -1 != card.getExitAnim()) && context instanceof Activity) { + ((Activity) context).overridePendingTransition(card.getEnterAnim(), card.getExitAnim()); + } + + logger.debug(null, "[goActivity] [onArrival] Complete!"); + if (callback != null) { + callback.onArrival(card); + } + }); + } + + @NonNull + private Object goFragment(Card card, GoCallback callback) { + try { + Object instance = card.getPathClass().getConstructor().newInstance(); + if (instance instanceof Fragment) { + ((Fragment) instance).setArguments(card.getExtras()); + } + runInMainThread(() -> { + logger.debug(null, "[goFragment] [onArrival] Complete!"); + if (callback != null) { + callback.onArrival(card); + } + }); + return instance; + } catch (Exception e) { + e.printStackTrace(); + throw new RouterException("fragment constructor new instance failed!"); + } + } + +} diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/callback/GoCallback.java b/GoRouter-Api/src/main/java/com/wyjson/router/callback/GoCallback.java index 7210dcf..2d8e3a1 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/callback/GoCallback.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/callback/GoCallback.java @@ -2,7 +2,7 @@ import androidx.annotation.NonNull; -import com.wyjson.router.card.Card; +import com.wyjson.router.model.Card; public interface GoCallback { diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorCallback.java b/GoRouter-Api/src/main/java/com/wyjson/router/callback/InterceptorCallback.java similarity index 70% rename from GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorCallback.java rename to GoRouter-Api/src/main/java/com/wyjson/router/callback/InterceptorCallback.java index 7360c66..311111d 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorCallback.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/callback/InterceptorCallback.java @@ -1,8 +1,8 @@ -package com.wyjson.router.interceptor; +package com.wyjson.router.callback; import androidx.annotation.NonNull; -import com.wyjson.router.card.Card; +import com.wyjson.router.model.Card; public interface InterceptorCallback { diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/callback/GoCallbackImpl.java b/GoRouter-Api/src/main/java/com/wyjson/router/callback/impl/GoCallbackImpl.java similarity index 75% rename from GoRouter-Api/src/main/java/com/wyjson/router/callback/GoCallbackImpl.java rename to GoRouter-Api/src/main/java/com/wyjson/router/callback/impl/GoCallbackImpl.java index b5eaf24..ee1e8dd 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/callback/GoCallbackImpl.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/callback/impl/GoCallbackImpl.java @@ -1,8 +1,9 @@ -package com.wyjson.router.callback; +package com.wyjson.router.callback.impl; import androidx.annotation.NonNull; -import com.wyjson.router.card.Card; +import com.wyjson.router.callback.GoCallback; +import com.wyjson.router.model.Card; public abstract class GoCallbackImpl implements GoCallback { @Override diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/GoRouter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/GoRouter.java deleted file mode 100644 index 9967b58..0000000 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/GoRouter.java +++ /dev/null @@ -1,472 +0,0 @@ -package com.wyjson.router.core; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.Application; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.ActivityCompat; -import androidx.fragment.app.Fragment; - -import com.wyjson.router.callback.GoCallback; -import com.wyjson.router.card.Card; -import com.wyjson.router.card.CardMeta; -import com.wyjson.router.enums.ParamType; -import com.wyjson.router.exception.RouterException; -import com.wyjson.router.interceptor.InterceptorCallback; -import com.wyjson.router.interceptor.InterceptorHelper; -import com.wyjson.router.interceptor.service.InterceptorService; -import com.wyjson.router.interceptor.service.impl.InterceptorServiceImpl; -import com.wyjson.router.interfaces.DegradeService; -import com.wyjson.router.interfaces.IInterceptor; -import com.wyjson.router.interfaces.IService; -import com.wyjson.router.interfaces.PretreatmentService; -import com.wyjson.router.load.RouteModuleLoadUtils; -import com.wyjson.router.logger.DefaultLogger; -import com.wyjson.router.logger.ILogger; -import com.wyjson.router.param.ParamMeta; -import com.wyjson.router.route.RouteHelper; -import com.wyjson.router.service.ServiceHelper; -import com.wyjson.router.thread.DefaultPoolExecutor; -import com.wyjson.router.utils.MapUtils; -import com.wyjson.router.utils.TextUtils; - -import java.lang.reflect.Field; -import java.util.Map; -import java.util.concurrent.ThreadPoolExecutor; - -public final class GoRouter { - - public static final String ROUTER_CURRENT_PATH = "go_router_current_path"; - public static final String ROUTER_RAW_URI = "go_router_raw_uri"; - - private final Handler mHandler = new Handler(Looper.getMainLooper()); - private volatile static ThreadPoolExecutor executor = DefaultPoolExecutor.getInstance(); - public static ILogger logger = new DefaultLogger("GoRouter"); - private volatile static boolean isDebug = false; - - private GoRouter() { - logger.info(null, "[GoRouter] constructor!"); - InterceptorHelper.getInstance().clearIterator(); - ServiceHelper.getInstance().addService(InterceptorServiceImpl.class); - } - - private static class InstanceHolder { - private static final GoRouter mInstance = new GoRouter(); - } - - public static GoRouter getInstance() { - return InstanceHolder.mInstance; - } - - /** - * 自动加载模块路由 - * - * @param application - */ - public static synchronized void autoLoadModuleRoute(Application application) { - logger.info(null, "[GoRouter] autoLoadModuleRoute!"); - RouteModuleLoadUtils.loadModuleRoute(application); - } - - /** - * 获取路由注册模式 - * - * @return true [GoRouter-Gradle-Plugin] ,false [scan dex file] - */ - public boolean isRouteRegisterMode() { - return RouteModuleLoadUtils.isRegisterByPlugin(); - } - - public static synchronized void openDebug() { - isDebug = true; - logger.showLog(isDebug); - logger.info(null, "[openDebug]"); - } - - public static boolean isDebug() { - return isDebug; - } - - public static synchronized void printStackTrace() { - logger.showStackTrace(true); - logger.info(null, "[printStackTrace]"); - } - - public static synchronized void setExecutor(ThreadPoolExecutor tpe) { - executor = tpe; - } - - public ThreadPoolExecutor getExecutor() { - return executor; - } - - public static void setLogger(ILogger userLogger) { - if (userLogger != null) { - logger = userLogger; - } - } - - /** - * 实现相同接口的service会被覆盖(更新) - * 调用时机可以在application或插件模块加载时 - * - * @param service 实现类.class - */ - public void addService(Class service) { - ServiceHelper.getInstance().addService(service); - } - - /** - * 获取service接口的实现 - * - * @param service 接口.class - * @param - * @return - */ - @Nullable - public T getService(Class service) { - return ServiceHelper.getInstance().getService(service); - } - - /** - * 相同优先级添加会catch - * 调用时机可以在application或插件模块加载时 - * - * @param priority - * @param interceptor - */ - public void addInterceptor(int priority, Class interceptor) { - InterceptorHelper.getInstance().addInterceptor(priority, interceptor, false); - } - - /** - * 相同优先级添加会覆盖 - * 调用时机可以在application或插件模块加载时 - * - * @param priority - * @param interceptor - */ - public void setInterceptor(int priority, Class interceptor) { - InterceptorHelper.getInstance().setInterceptor(priority, interceptor); - } - - public Card build(String path) { - return build(path, null); - } - - public Card build(String path, Bundle bundle) { - return new Card(path, bundle); - } - - public Card build(Uri uri) { - return new Card(uri); - } - - private void runInMainThread(Runnable runnable) { - if (Looper.getMainLooper().getThread() != Thread.currentThread()) { - mHandler.post(runnable); - } else { - runnable.run(); - } - } - - public void inject(Activity activity) { - inject(activity, null, null); - } - - public void inject(Activity activity, Intent intent) { - inject(activity, intent, null); - } - - public void inject(Activity activity, Bundle bundle) { - inject(activity, null, bundle); - } - - public void inject(Fragment fragment) { - inject(fragment, null, null); - } - - public void inject(Fragment fragment, Intent intent) { - inject(fragment, intent, null); - } - - public void inject(Fragment fragment, Bundle bundle) { - inject(fragment, null, bundle); - } - - /** - * 解析参数 - * - * @param target - * @param intent - * @param bundle - * @param - */ - private void inject(T target, Intent intent, Bundle bundle) { - logger.debug(null, "[inject] Auto Inject Start!"); - - if (bundle == null) { - if (intent != null) { - bundle = intent.getExtras(); - } else { - if (target instanceof Activity) { - bundle = ((Activity) target).getIntent().getExtras(); - } else if (target instanceof Fragment) { - bundle = ((Fragment) target).getArguments(); - } - } - if (bundle == null) { - throw new RouterException("inject() method does not get bundle!"); - } - } - - String path = bundle.getString(GoRouter.ROUTER_CURRENT_PATH); - if (TextUtils.isEmpty(path)) { - logger.error(null, "[inject] path Parameter is invalid!"); - return; - } - - CardMeta cardMeta = GoRouter.getInstance().build(path).getCardMeta(); - if (cardMeta != null) { - Map paramsType = cardMeta.getParamsType(); - for (Map.Entry params : paramsType.entrySet()) { - String paramName = params.getValue().getName(); - Object value = bundle.get(paramName); - if (value == null) - continue; - logger.debug(null, "[inject] " + paramName + ":" + value); - try { - Field injectField = getDeclaredField(target.getClass(), params.getKey()); - injectField.setAccessible(true); - injectField.set(target, value); - } catch (Exception e) { - throw new RouterException("Inject values for activity/fragment error! [" + e.getMessage() + "]"); - } - } - } - logger.debug(null, "[inject] Auto Inject End!"); - } - - @NonNull - private static Field getDeclaredField(Class cls, String key) throws NoSuchFieldException { - try { - return cls.getDeclaredField(key); - } catch (NoSuchFieldException e) { - Class superclass = cls.getSuperclass(); - if (superclass != null && !superclass.getName().startsWith("android")) { - return getDeclaredField(superclass, key); - } else { - throw new NoSuchFieldException(e.getMessage()); - } - } - } - - @Nullable - public Object go(Context context, Card card, int requestCode, GoCallback callback) { - card.setContext(context); - card.setInterceptorException(null); - card.withString(GoRouter.ROUTER_CURRENT_PATH, card.getPath()); - - logger.debug(null, "[go] " + card); - PretreatmentService pretreatmentService = getService(PretreatmentService.class); - if (pretreatmentService != null) { - if (!pretreatmentService.onPretreatment(context, card)) { - // 预处理失败,导航取消 - logger.debug(null, "[go] PretreatmentService Failure!"); - return null; - } - } else { - logger.warning(null, "[go] This [PretreatmentService] was not found!"); - } - - CardMeta cardMeta = card.getCardMeta(); - if (cardMeta != null) { - card.setCardMeta(cardMeta.getType(), cardMeta.getPathClass(), cardMeta.getTag()); - - Map paramsType = cardMeta.getParamsType(); - Uri rawUri = card.getUri(); - if (rawUri != null) { - Map resultMap = TextUtils.splitQueryParameters(rawUri); - if (MapUtils.isNotEmpty(paramsType)) { - // 按类型设置值 - for (Map.Entry params : paramsType.entrySet()) { - setValue(card, - params.getValue().getType(), - params.getValue().getName(), - resultMap.get(params.getKey())); - } - } - // 保存原始uri - card.withString(GoRouter.ROUTER_RAW_URI, rawUri.toString()); - } - - runInMainThread(() -> { - logger.debug(null, "[go] [onFound] " + card); - if (callback != null) { - callback.onFound(card); - } - }); - - switch (card.getType()) { - case ACTIVITY: - InterceptorService interceptorService = getService(InterceptorService.class); - if (interceptorService != null && !card.isGreenChannel()) { - interceptorService.doInterceptions(card, new InterceptorCallback() { - @Override - public void onContinue(Card card) { - goActivity(context, card, requestCode, cardMeta.getPathClass(), callback); - } - - @Override - public void onInterrupt(Card card, @NonNull Throwable exception) { - runInMainThread(() -> { - if (callback != null) { - callback.onInterrupt(card, exception); - } - }); - } - }); - } else { - goActivity(context, card, requestCode, cardMeta.getPathClass(), callback); - } - break; - case FRAGMENT: - return goFragment(card, cardMeta.getPathClass(), callback); - } - } else { - onLost(context, card, callback); - } - return null; - } - - /** - * 按已知类型设置值 - * - * @param card - * @param type - * @param key - * @param value - */ - private void setValue(Card card, ParamType type, String key, String value) { - if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) - return; - try { - if (type != null) { - if (type == ParamType.Boolean) { - card.withBoolean(key, Boolean.parseBoolean(value)); - } else if (type == ParamType.Byte) { - card.withByte(key, Byte.parseByte(value)); - } else if (type == ParamType.Short) { - card.withShort(key, Short.parseShort(value)); - } else if (type == ParamType.Int) { - card.withInt(key, Integer.parseInt(value)); - } else if (type == ParamType.Long) { - card.withLong(key, Long.parseLong(value)); - } else if (type == ParamType.Char) { - card.withChar(key, value.charAt(0)); - } else if (type == ParamType.Float) { - card.withFloat(key, Float.parseFloat(value)); - } else if (type == ParamType.Double) { - card.withDouble(key, Double.parseDouble(value)); - } else if (type == ParamType.String) { - card.withString(key, value); - } else if (type == ParamType.Parcelable) { - // TODO : How to description parcelable value with string? - } else { - card.withString(key, value); - } - } else { - card.withString(key, value); - } - } catch (Throwable e) { - throw new RouterException("setValue() failed! " + e.getMessage()); - } - } - - private void onLost(Context context, Card card, GoCallback callback) { - runInMainThread(() -> { - logger.error(null, "[onLost] There is no route. path[" + card.getPath() + "]"); - if (callback != null) { - callback.onLost(card); - } else { - DegradeService degradeService = getService(DegradeService.class); - if (degradeService != null) { - degradeService.onLost(context, card); - } else { - logger.warning(null, "[onLost] This [DegradeService] was not found!"); - } - } - }); - } - - @SuppressLint("WrongConstant") - private void goActivity(Context context, Card card, int requestCode, Class cls, GoCallback callback) { - Intent intent = new Intent(context, cls); - - intent.putExtras(card.getExtras()); - - int flags = card.getFlags(); - if (0 != flags) { - intent.setFlags(flags); - } - - if (!(context instanceof Activity)) { - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - } - - String action = card.getAction(); - if (!TextUtils.isEmpty(action)) { - intent.setAction(action); - } - - runInMainThread(() -> { - if (requestCode >= 0) { - if (context instanceof Activity) { - ActivityCompat.startActivityForResult((Activity) context, intent, requestCode, card.getOptionsBundle()); - } else { - throw new RouterException("Must use [go(activity, ...)] to support [startActivityForResult]!"); - } - } else { - ActivityCompat.startActivity(context, intent, card.getOptionsBundle()); - } - - if ((-1 != card.getEnterAnim() && -1 != card.getExitAnim()) && context instanceof Activity) { - ((Activity) context).overridePendingTransition(card.getEnterAnim(), card.getExitAnim()); - } - - logger.debug(null, "[goActivity] [onArrival] Complete!"); - if (callback != null) { - callback.onArrival(card); - } - }); - } - - @NonNull - private Object goFragment(Card card, Class cls, GoCallback callback) { - try { - Object instance = cls.getConstructor().newInstance(); - if (instance instanceof Fragment) { - ((Fragment) instance).setArguments(card.getExtras()); - } - runInMainThread(() -> { - logger.debug(null, "[goFragment] [onArrival] Complete!"); - if (callback != null) { - callback.onArrival(card); - } - }); - return instance; - } catch (Exception e) { - e.printStackTrace(); - throw new RouterException("fragment constructor new instance failed!"); - } - } - -} diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/service/impl/InterceptorServiceImpl.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/InterceptorServiceImpl.java similarity index 79% rename from GoRouter-Api/src/main/java/com/wyjson/router/interceptor/service/impl/InterceptorServiceImpl.java rename to GoRouter-Api/src/main/java/com/wyjson/router/core/InterceptorServiceImpl.java index 0101970..8ed762e 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/service/impl/InterceptorServiceImpl.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/InterceptorServiceImpl.java @@ -1,13 +1,12 @@ -package com.wyjson.router.interceptor.service.impl; +package com.wyjson.router.core; import androidx.annotation.NonNull; -import com.wyjson.router.card.Card; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; +import com.wyjson.router.callback.InterceptorCallback; +import com.wyjson.router.model.Card; +import com.wyjson.router.core.interfaces.IInterceptorService; import com.wyjson.router.exception.RouterException; -import com.wyjson.router.interceptor.InterceptorCallback; -import com.wyjson.router.interceptor.InterceptorHelper; -import com.wyjson.router.interceptor.service.InterceptorService; import com.wyjson.router.interfaces.IInterceptor; import com.wyjson.router.thread.CancelableCountDownLatch; import com.wyjson.router.utils.MapUtils; @@ -16,17 +15,17 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -public class InterceptorServiceImpl implements InterceptorService { +public class InterceptorServiceImpl implements IInterceptorService { @Override public void doInterceptions(Card card, InterceptorCallback callback) { - GoRouter.logger.info(null, "[doInterceptions] " + InterceptorHelper.getInstance().getInterceptors()); - if (MapUtils.isNotEmpty(InterceptorHelper.getInstance().getInterceptors())) { - Iterator> iterator = InterceptorHelper.getInstance().getInterceptors().entrySet().iterator(); + GoRouter.logger.info(null, "[doInterceptions] " + Warehouse.interceptors); + if (MapUtils.isNotEmpty(Warehouse.interceptors)) { + Iterator> iterator = Warehouse.interceptors.entrySet().iterator(); GoRouter.getInstance().getExecutor().execute(new Runnable() { @Override public void run() { - CancelableCountDownLatch interceptorCounter = new CancelableCountDownLatch(InterceptorHelper.getInstance().getInterceptors().size()); + CancelableCountDownLatch interceptorCounter = new CancelableCountDownLatch(Warehouse.interceptors.size()); try { execute(card, iterator, interceptorCounter); interceptorCounter.await(card.getTimeout(), TimeUnit.SECONDS); diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java new file mode 100644 index 0000000..581df5f --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java @@ -0,0 +1,315 @@ +package com.wyjson.router.core; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.wyjson.router.GoRouter; +import com.wyjson.router.enums.ParamType; +import com.wyjson.router.exception.NoFoundRouteException; +import com.wyjson.router.exception.RouterException; +import com.wyjson.router.interfaces.IInterceptor; +import com.wyjson.router.interfaces.IService; +import com.wyjson.router.model.Card; +import com.wyjson.router.model.CardMeta; +import com.wyjson.router.model.ParamMeta; +import com.wyjson.router.model.ServiceMeta; +import com.wyjson.router.module.interfaces.IRouteModuleGroup; +import com.wyjson.router.utils.MapUtils; +import com.wyjson.router.utils.TextUtils; + +import java.lang.reflect.Field; +import java.util.Map; + +public class LogisticsCenter { + + public static Map getRouteGroups() { + return Warehouse.routeGroups; + } + + public static CardMeta getCardMeta(Card card) throws NoFoundRouteException { + CardMeta cardMeta = Warehouse.routes.get(card.getPath()); + if (cardMeta == null) { + if (!Warehouse.routeGroups.containsKey(card.getGroup())) { + throw new NoFoundRouteException("There is no route match the path [" + card.getPath() + "], in group [" + card.getGroup() + "]"); + } else { + try { + if (GoRouter.isDebug()) { + GoRouter.logger.debug(null, "[getCardMeta] The group [" + card.getGroup() + "] starts loading, trigger by [" + card.getPath() + "]"); + } + + // Load route and cache it into memory, then delete from metas. + if (Warehouse.routeGroups.containsKey(card.getGroup())) { + // If this group is included, but it has not been loaded + // load this group first, because dynamic route has high priority. + Warehouse.routeGroups.get(card.getGroup()).load(); + Warehouse.routeGroups.remove(card.getGroup()); + } + + if (GoRouter.isDebug()) { + GoRouter.logger.debug(null, "[getCardMeta] The group [" + card.getGroup() + "] has already been loaded, trigger by [" + card.getPath() + "]"); + } + } catch (Exception e) { + throw new RouterException("Fatal exception when loading group meta. [" + e.getMessage() + "]"); + } + return getCardMeta(card);// Reload + } + } else { + GoRouter.logger.info(null, "[getCardMeta] " + cardMeta); + } + return cardMeta; + } + + public static void addCardMeta(CardMeta cardMeta) { + if (TextUtils.isEmpty(cardMeta.getPath())) { + throw new RouterException("path Parameter is invalid!"); + } + // 检查路由是否有重复提交的情况 + if (GoRouter.isDebug()) { + for (Map.Entry cardMetaEntry : Warehouse.routes.entrySet()) { + if (TextUtils.equals(cardMetaEntry.getKey(), cardMeta.getPath())) { + GoRouter.logger.error(null, "[addCardMeta] Path duplicate commit!!! path[" + cardMetaEntry.getValue().getPath() + "]"); + break; + } else if (cardMetaEntry.getValue().getPathClass() == cardMeta.getPathClass()) { + GoRouter.logger.error(null, "[addCardMeta] PathClass duplicate commit!!! pathClass[" + cardMetaEntry.getValue().getPathClass() + "]"); + break; + } + } + } + Warehouse.routes.put(cardMeta.getPath(), cardMeta); + GoRouter.logger.debug(null, "[addCardMeta] size:" + Warehouse.routes.size() + ", commit:" + cardMeta); + } + + + /** + * 实现相同接口的service会被覆盖(更新) + * 调用时机可以在application或插件模块加载时 + * + * @param serviceClass 实现类.class + */ + public static void addService(Class serviceClass) { + Class serviceInterfaceClass = (Class) serviceClass.getInterfaces()[0]; + Warehouse.services.put(serviceInterfaceClass, new ServiceMeta(serviceClass)); + GoRouter.logger.debug(null, "[addService] size:" + Warehouse.services.size() + ", " + serviceInterfaceClass.getSimpleName() + " -> " + serviceClass.getSimpleName()); + } + + /** + * 获取service接口的实现 + * + * @param serviceClass 接口.class + * @param + * @return + */ + @Nullable + public static T getService(Class serviceClass) { + ServiceMeta meta = Warehouse.services.get(serviceClass); + if (meta != null) { + if (serviceClass.isAssignableFrom(meta.getServiceClass())) { + IService instance = meta.getService(); + if (instance == null) { + try { + instance = meta.getServiceClass().getConstructor().newInstance(); + instance.init(); + meta.setService(instance); + } catch (Exception e) { + e.printStackTrace(); + throw new RouterException("serviceClass constructor new instance failed!"); + } + } + GoRouter.logger.info(null, "[getService] " + serviceClass.getSimpleName() + " -> " + meta.getServiceClass().getSimpleName()); + return (T) instance; + } + } + GoRouter.logger.warning(null, "[getService] " + serviceClass.getSimpleName() + ", No registered service found!"); + return null; + } + + /** + * 相同优先级添加会catch + * 调用时机可以在application或插件模块加载时 + * + * @param priority + * @param interceptor + * @param isForce + */ + public static void addInterceptor(int priority, Class interceptor, boolean isForce) { + try { + if (isForce) { + Warehouse.interceptors.remove(priority); + } + IInterceptor instance = interceptor.getConstructor().newInstance(); + instance.init(); + Warehouse.interceptors.put(priority, instance); + + String title = isForce ? "[setInterceptor]" : "[addInterceptor]"; + GoRouter.logger.debug(null, title + " size:" + Warehouse.interceptors.size() + ", priority:" + priority + " -> " + interceptor.getSimpleName()); + } catch (Exception e) { + throw new RouterException(e); + } + } + + /** + * 相同优先级添加会覆盖 + * 调用时机可以在application或插件模块加载时 + * + * @param priority + * @param interceptor + */ + public static void setInterceptor(int priority, Class interceptor) { + addInterceptor(priority, interceptor, true); + } + + public static void clearInterceptors() { + Warehouse.interceptors.clear(); + } + + + /** + * 解析参数 + * + * @param target + * @param intent + * @param bundle + * @param + */ + public static void inject(T target, Intent intent, Bundle bundle) { + GoRouter.logger.debug(null, "[inject] Auto Inject Start!"); + + if (bundle == null) { + if (intent != null) { + bundle = intent.getExtras(); + } else { + if (target instanceof Activity) { + bundle = ((Activity) target).getIntent().getExtras(); + } else if (target instanceof Fragment) { + bundle = ((Fragment) target).getArguments(); + } + } + if (bundle == null) { + throw new RouterException("inject() method does not get bundle!"); + } + } + + String path = bundle.getString(GoRouter.ROUTER_CURRENT_PATH); + if (TextUtils.isEmpty(path)) { + GoRouter.logger.error(null, "[inject] path Parameter is invalid!"); + return; + } + + CardMeta cardMeta = GoRouter.getInstance().build(path).getCardMeta(); + if (cardMeta != null) { + Map paramsType = cardMeta.getParamsType(); + for (Map.Entry params : paramsType.entrySet()) { + String paramName = params.getValue().getName(); + Object value = bundle.get(paramName); + if (value == null) + continue; + GoRouter.logger.debug(null, "[inject] " + paramName + ":" + value); + try { + Field injectField = getDeclaredField(target.getClass(), params.getKey()); + injectField.setAccessible(true); + injectField.set(target, value); + } catch (Exception e) { + throw new RouterException("Inject values for activity/fragment error! [" + e.getMessage() + "]"); + } + } + } + GoRouter.logger.debug(null, "[inject] Auto Inject End!"); + } + + /** + * 本类找不到就去父类里找,到Android类停止查找 + * + * @param cls + * @param key + * @return + * @throws NoSuchFieldException + */ + @NonNull + private static Field getDeclaredField(Class cls, String key) throws NoSuchFieldException { + try { + return cls.getDeclaredField(key); + } catch (NoSuchFieldException e) { + Class superclass = cls.getSuperclass(); + if (superclass != null && !superclass.getName().startsWith("android")) { + return getDeclaredField(superclass, key); + } else { + throw new NoSuchFieldException(e.getMessage()); + } + } + } + + public static synchronized void assembleRouteCard(@NonNull Card card) throws NoFoundRouteException { + CardMeta cardMeta = getCardMeta(card); + if (cardMeta != null) { + card.setCardMeta(cardMeta.getType(), cardMeta.getPathClass(), cardMeta.getTag()); + + Map paramsType = cardMeta.getParamsType(); + Uri rawUri = card.getUri(); + if (rawUri != null) { + Map resultMap = TextUtils.splitQueryParameters(rawUri); + if (MapUtils.isNotEmpty(paramsType)) { + // 按类型设置值 + for (Map.Entry params : paramsType.entrySet()) { + setValue(card, + params.getValue().getType(), + params.getValue().getName(), + resultMap.get(params.getKey())); + } + } + // 保存原始uri + card.withString(GoRouter.ROUTER_RAW_URI, rawUri.toString()); + } + } + } + + /** + * 按已知类型设置值 + * + * @param card + * @param type + * @param key + * @param value + */ + private static void setValue(Card card, ParamType type, String key, String value) { + if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) + return; + try { + if (type != null) { + if (type == ParamType.Boolean) { + card.withBoolean(key, Boolean.parseBoolean(value)); + } else if (type == ParamType.Byte) { + card.withByte(key, Byte.parseByte(value)); + } else if (type == ParamType.Short) { + card.withShort(key, Short.parseShort(value)); + } else if (type == ParamType.Int) { + card.withInt(key, Integer.parseInt(value)); + } else if (type == ParamType.Long) { + card.withLong(key, Long.parseLong(value)); + } else if (type == ParamType.Char) { + card.withChar(key, value.charAt(0)); + } else if (type == ParamType.Float) { + card.withFloat(key, Float.parseFloat(value)); + } else if (type == ParamType.Double) { + card.withDouble(key, Double.parseDouble(value)); + } else if (type == ParamType.String) { + card.withString(key, value); + } else if (type == ParamType.Parcelable) { + // TODO : How to description parcelable value with string? + } else { + card.withString(key, value); + } + } else { + card.withString(key, value); + } + } catch (Throwable e) { + throw new RouterException("setValue() failed! " + e.getMessage()); + } + } + +} diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/load/RouteModuleLoadUtils.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java similarity index 82% rename from GoRouter-Api/src/main/java/com/wyjson/router/load/RouteModuleLoadUtils.java rename to GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java index 55d79f8..09e0d32 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/load/RouteModuleLoadUtils.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java @@ -1,13 +1,11 @@ -package com.wyjson.router.load; +package com.wyjson.router.core; import android.app.Application; import android.content.Context; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; import com.wyjson.router.exception.RouterException; -import com.wyjson.router.interceptor.InterceptorHelper; -import com.wyjson.router.route.RouteHelper; -import com.wyjson.router.service.ServiceHelper; +import com.wyjson.router.module.interfaces.IRouteModule; import com.wyjson.router.utils.ClassUtils; import com.wyjson.router.utils.PackageUtils; import com.wyjson.router.utils.TextUtils; @@ -16,7 +14,7 @@ import java.util.Locale; import java.util.Set; -public class RouteModuleLoadUtils { +public class RouteModuleLoadCenter { private static boolean registerByPlugin; @@ -29,7 +27,7 @@ public static boolean isRegisterByPlugin() { return registerByPlugin; } - public static void loadModuleRoute(Application application) { + public static synchronized void loadModuleRoute(Application application) { loadModuleRouteByPlugin(); if (registerByPlugin) { GoRouter.logger.info(null, "Loading mode: Load routes by [GoRouter-Gradle-Plugin] plugin."); @@ -38,18 +36,16 @@ public static void loadModuleRoute(Application application) { loadModuleRouteByDex(application); } - if (RouteHelper.getInstance().getRoutes().size() == 0 - && ServiceHelper.getInstance().getServices().size() <= 1 // 本库默认自带了一个不算在内 - && InterceptorHelper.getInstance().getInterceptors().size() == 0) { + if (Warehouse.routeGroups.size() == 0) { GoRouter.logger.error(null, "No mapping files were found, check your configuration please!"); } if (GoRouter.isDebug()) { GoRouter.logger.debug(null, String.format(Locale.getDefault(), - "GoRouter has already been loaded, RouteIndex[%d], ServiceIndex[%d], InterceptorIndex[%d]", - RouteHelper.getInstance().getRoutes().size(), - ServiceHelper.getInstance().getServices().size(), - InterceptorHelper.getInstance().getInterceptors().size() + "GoRouter has already been loaded, RouteGroupIndex[%d], ServiceIndex[%d], InterceptorIndex[%d]", + Warehouse.routeGroups.size(), + Warehouse.services.size(), + Warehouse.interceptors.size() )); } } @@ -107,7 +103,11 @@ private static void markRegisteredByPlugin() { public static final String GOROUTER_SP_CACHE_KEY = "SP_GOROUTER_CACHE"; public static final String GOROUTER_SP_KEY_MAP = "ROUTE_MODULE_MAP"; - public static final String ROUTE_MODULE_PAKCAGE = "com.wyjson.router.module"; + public static final String SEPARATOR = "$$"; + // 路由注册生成类所在包名 + public static final String ROUTE_MODULE_PACKAGE = "com.wyjson.router.module"; + // 路由注册生成类名后缀$$GoRouter + public static final String MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "GoRouter"; private static void loadModuleRouteByDex(Application context) { try { @@ -116,7 +116,7 @@ private static void loadModuleRouteByDex(Application context) { if (GoRouter.isDebug() || PackageUtils.isNewVersion(context)) { GoRouter.logger.info(null, "Run with debug mode or new install, rebuild router map."); // These class was generated by GoRouter-Compiler. - routeModuleMap = ClassUtils.getFileNameByPackageName(context, ROUTE_MODULE_PAKCAGE); + routeModuleMap = ClassUtils.getFileNameByPackageName(context, ROUTE_MODULE_PACKAGE, MODULE_ROUTE_NAME_SUFFIX); if (!routeModuleMap.isEmpty()) { context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(GOROUTER_SP_KEY_MAP, routeModuleMap).apply(); } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java new file mode 100644 index 0000000..739d709 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java @@ -0,0 +1,22 @@ +package com.wyjson.router.core; + +import com.wyjson.router.interfaces.IInterceptor; +import com.wyjson.router.interfaces.IService; +import com.wyjson.router.model.CardMeta; +import com.wyjson.router.model.ServiceMeta; +import com.wyjson.router.module.interfaces.IRouteModuleGroup; +import com.wyjson.router.utils.InterceptorTreeMap; + +import java.util.HashMap; +import java.util.Map; + +class Warehouse { + + static final Map routeGroups = new HashMap<>(); + static final Map routes = new HashMap<>(); + + static final Map, ServiceMeta> services = new HashMap<>(); + + static final Map interceptors = new InterceptorTreeMap<>("More than one interceptors use same priority [%s]"); + +} diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/interfaces/IInterceptorService.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/interfaces/IInterceptorService.java new file mode 100644 index 0000000..5f53a97 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/interfaces/IInterceptorService.java @@ -0,0 +1,9 @@ +package com.wyjson.router.core.interfaces; + +import com.wyjson.router.callback.InterceptorCallback; +import com.wyjson.router.model.Card; +import com.wyjson.router.interfaces.IService; + +public interface IInterceptorService extends IService { + void doInterceptions(Card card, InterceptorCallback callback); +} \ No newline at end of file diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/exception/NoFoundRouteException.java b/GoRouter-Api/src/main/java/com/wyjson/router/exception/NoFoundRouteException.java new file mode 100644 index 0000000..66727f8 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/exception/NoFoundRouteException.java @@ -0,0 +1,9 @@ +package com.wyjson.router.exception; + +public class NoFoundRouteException extends RuntimeException { + + public NoFoundRouteException(String message) { + super(message); + } + +} diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorHelper.java b/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorHelper.java deleted file mode 100644 index e647ba8..0000000 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorHelper.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.wyjson.router.interceptor; - -import com.wyjson.router.core.GoRouter; -import com.wyjson.router.exception.RouterException; -import com.wyjson.router.interfaces.IInterceptor; - -import java.util.Map; - -public class InterceptorHelper { - - private InterceptorHelper() { - } - - private static class InstanceHolder { - private static final InterceptorHelper mInstance = new InterceptorHelper(); - } - - public static InterceptorHelper getInstance() { - return InterceptorHelper.InstanceHolder.mInstance; - } - - private static final Map interceptors = new InterceptorTreeMap<>("More than one interceptors use same priority [%s]"); - - public Map getInterceptors() { - return interceptors; - } - - /** - * 相同优先级添加会catch - * 调用时机可以在application或插件模块加载时 - * - * @param priority - * @param interceptor - * @param isForce - */ - public void addInterceptor(int priority, Class interceptor, boolean isForce) { - try { - if (isForce) { - interceptors.remove(priority); - } - IInterceptor instance = interceptor.getConstructor().newInstance(); - instance.init(); - interceptors.put(priority, instance); - - String title = isForce ? "[setInterceptor]" : "[addInterceptor]"; - GoRouter.logger.debug(null, title + " size:" + interceptors.size() + ", priority:" + priority + " -> " + interceptor.getSimpleName()); - } catch (Exception e) { - throw new RouterException(e); - } - } - - /** - * 相同优先级添加会覆盖 - * 调用时机可以在application或插件模块加载时 - * - * @param priority - * @param interceptor - */ - public void setInterceptor(int priority, Class interceptor) { - addInterceptor(priority, interceptor, true); - } - - public void clearIterator() { - interceptors.clear(); - } -} \ No newline at end of file diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/service/InterceptorService.java b/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/service/InterceptorService.java deleted file mode 100644 index fe697c4..0000000 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/service/InterceptorService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.wyjson.router.interceptor.service; - -import com.wyjson.router.card.Card; -import com.wyjson.router.interceptor.InterceptorCallback; -import com.wyjson.router.interfaces.IService; - -public interface InterceptorService extends IService { - void doInterceptions(Card card, InterceptorCallback callback); -} \ No newline at end of file diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/DegradeService.java b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IDegradeService.java similarity index 69% rename from GoRouter-Api/src/main/java/com/wyjson/router/interfaces/DegradeService.java rename to GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IDegradeService.java index a3a6e6b..1123152 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/DegradeService.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IDegradeService.java @@ -2,12 +2,12 @@ import android.content.Context; -import com.wyjson.router.card.Card; +import com.wyjson.router.model.Card; /** * 为路由器提供降级服务,可以在路由丢失时采取措施。 */ -public interface DegradeService extends IService { +public interface IDegradeService extends IService { void onLost(Context context, Card card); } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IInterceptor.java b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IInterceptor.java index 55a547c..68bb05e 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IInterceptor.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IInterceptor.java @@ -1,7 +1,7 @@ package com.wyjson.router.interfaces; -import com.wyjson.router.card.Card; -import com.wyjson.router.interceptor.InterceptorCallback; +import com.wyjson.router.model.Card; +import com.wyjson.router.callback.InterceptorCallback; /** * 拦截器 diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/PretreatmentService.java b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IPretreatmentService.java similarity index 78% rename from GoRouter-Api/src/main/java/com/wyjson/router/interfaces/PretreatmentService.java rename to GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IPretreatmentService.java index 0040ec9..97a26c2 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/PretreatmentService.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IPretreatmentService.java @@ -2,12 +2,12 @@ import android.content.Context; -import com.wyjson.router.card.Card; +import com.wyjson.router.model.Card; /** * 预处理 */ -public interface PretreatmentService extends IService { +public interface IPretreatmentService extends IService { /** * 跳转前预处理 diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java b/GoRouter-Api/src/main/java/com/wyjson/router/model/Card.java similarity index 95% rename from GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java rename to GoRouter-Api/src/main/java/com/wyjson/router/model/Card.java index 93cd189..a4ec2e4 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/card/Card.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/model/Card.java @@ -1,21 +1,23 @@ -package com.wyjson.router.card; +package com.wyjson.router.model; import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.util.SparseArray; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.core.app.ActivityOptionsCompat; +import com.wyjson.router.GoRouter; import com.wyjson.router.callback.GoCallback; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.core.LogisticsCenter; import com.wyjson.router.enums.RouteType; +import com.wyjson.router.exception.NoFoundRouteException; import com.wyjson.router.exception.RouterException; -import com.wyjson.router.route.RouteHelper; import com.wyjson.router.utils.TextUtils; import java.io.Serializable; @@ -98,7 +100,12 @@ private Object go(Context context, Card card, int requestCode, GoCallback callba @Nullable public CardMeta getCardMeta() { - return RouteHelper.getInstance().getCardMeta(this); + try { + return LogisticsCenter.getCardMeta(this); + } catch (NoFoundRouteException e) { + GoRouter.logger.warning(null, e.getMessage()); + } + return null; } public void setCardMeta(RouteType type, Class pathClass, int tag) { diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java b/GoRouter-Api/src/main/java/com/wyjson/router/model/CardMeta.java similarity index 93% rename from GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java rename to GoRouter-Api/src/main/java/com/wyjson/router/model/CardMeta.java index 8ccffca..62dba04 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/card/CardMeta.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/model/CardMeta.java @@ -1,14 +1,13 @@ -package com.wyjson.router.card; +package com.wyjson.router.model; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; +import com.wyjson.router.core.LogisticsCenter; import com.wyjson.router.enums.ParamType; import com.wyjson.router.enums.RouteType; import com.wyjson.router.exception.RouterException; -import com.wyjson.router.param.ParamMeta; -import com.wyjson.router.route.RouteHelper; import com.wyjson.router.utils.TextUtils; import java.util.HashMap; @@ -63,7 +62,7 @@ private String extractGroup(String path) { return group; } } catch (Exception e) { - throw new RouterException("Failed to extract path[" + path + "] group! " + e.getMessage()); + throw new RouterException("Extract the path[" + path + "] group failed, the path must be start with '/' and contain more than 2 '/'! " + e.getMessage()); } } @@ -107,8 +106,8 @@ public void commitFragment(Class cls) { commit(cls, RouteType.FRAGMENT); } - public void commit(Class cls, RouteType type) { - RouteHelper.getInstance().addCardMeta(new CardMeta(this.path, type, cls, this.tag, this.paramsType)); + private void commit(Class cls, RouteType type) { + LogisticsCenter.addCardMeta(new CardMeta(this.path, type, cls, this.tag, this.paramsType)); } public CardMeta putTag(int tag) { diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/param/ParamMeta.java b/GoRouter-Api/src/main/java/com/wyjson/router/model/ParamMeta.java similarity index 93% rename from GoRouter-Api/src/main/java/com/wyjson/router/param/ParamMeta.java rename to GoRouter-Api/src/main/java/com/wyjson/router/model/ParamMeta.java index 561411f..5d0cdf5 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/param/ParamMeta.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/model/ParamMeta.java @@ -1,8 +1,8 @@ -package com.wyjson.router.param; +package com.wyjson.router.model; import androidx.annotation.NonNull; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; import com.wyjson.router.enums.ParamType; public class ParamMeta { diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/service/ServiceMeta.java b/GoRouter-Api/src/main/java/com/wyjson/router/model/ServiceMeta.java similarity index 93% rename from GoRouter-Api/src/main/java/com/wyjson/router/service/ServiceMeta.java rename to GoRouter-Api/src/main/java/com/wyjson/router/model/ServiceMeta.java index fc55f99..e8cde08 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/service/ServiceMeta.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/model/ServiceMeta.java @@ -1,4 +1,4 @@ -package com.wyjson.router.service; +package com.wyjson.router.model; import com.wyjson.router.interfaces.IService; diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModule.java b/GoRouter-Api/src/main/java/com/wyjson/router/module/interfaces/IRouteModule.java similarity index 79% rename from GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModule.java rename to GoRouter-Api/src/main/java/com/wyjson/router/module/interfaces/IRouteModule.java index 1cbec41..bee3dd2 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModule.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/module/interfaces/IRouteModule.java @@ -1,4 +1,4 @@ -package com.wyjson.router.load; +package com.wyjson.router.module.interfaces; /** * Do not use this interface. diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModuleGroup.java b/GoRouter-Api/src/main/java/com/wyjson/router/module/interfaces/IRouteModuleGroup.java similarity index 81% rename from GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModuleGroup.java rename to GoRouter-Api/src/main/java/com/wyjson/router/module/interfaces/IRouteModuleGroup.java index c541e35..9f797e5 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/load/IRouteModuleGroup.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/module/interfaces/IRouteModuleGroup.java @@ -1,4 +1,4 @@ -package com.wyjson.router.load; +package com.wyjson.router.module.interfaces; /** * Do not use this interface. diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/route/RouteHelper.java b/GoRouter-Api/src/main/java/com/wyjson/router/route/RouteHelper.java deleted file mode 100644 index 1db2752..0000000 --- a/GoRouter-Api/src/main/java/com/wyjson/router/route/RouteHelper.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.wyjson.router.route; - -import androidx.annotation.Nullable; - -import com.wyjson.router.card.Card; -import com.wyjson.router.card.CardMeta; -import com.wyjson.router.core.GoRouter; -import com.wyjson.router.exception.RouterException; -import com.wyjson.router.utils.TextUtils; - -import java.util.HashMap; -import java.util.Map; - -public class RouteHelper { - - private RouteHelper() { - } - - private static class InstanceHolder { - private static final RouteHelper mInstance = new RouteHelper(); - } - - public static RouteHelper getInstance() { - return InstanceHolder.mInstance; - } - - private static final Map routes = new HashMap<>(); - - public Map getRoutes() { - return routes; - } - - @Nullable - public CardMeta getCardMeta(Card card) { - CardMeta cardMeta = routes.get(card.getPath()); - if (cardMeta != null) { - GoRouter.logger.info(null, "[getCardMeta] " + cardMeta); - } else { - GoRouter.logger.warning(null, "[getCardMeta] null"); - } - return cardMeta; - } - - public void addCardMeta(CardMeta cardMeta) { - if (TextUtils.isEmpty(cardMeta.getPath())) { - throw new RouterException("path Parameter is invalid!"); - } - // 检查路由是否有重复提交的情况 - if (GoRouter.isDebug()) { - for (Map.Entry cardMetaEntry : routes.entrySet()) { - if (TextUtils.equals(cardMetaEntry.getKey(), cardMeta.getPath())) { - GoRouter.logger.error(null, "[addCardMeta] Path duplicate commit!!! path[" + cardMetaEntry.getValue().getPath() + "]"); - break; - } else if (cardMetaEntry.getValue().getPathClass() == cardMeta.getPathClass()) { - GoRouter.logger.error(null, "[addCardMeta] PathClass duplicate commit!!! pathClass[" + cardMetaEntry.getValue().getPathClass() + "]"); - break; - } - } - } - routes.put(cardMeta.getPath(), cardMeta); - GoRouter.logger.debug(null, "[addCardMeta] size:" + routes.size() + ", commit:" + cardMeta); - } - -} \ No newline at end of file diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/service/ServiceHelper.java b/GoRouter-Api/src/main/java/com/wyjson/router/service/ServiceHelper.java deleted file mode 100644 index fd3ff8e..0000000 --- a/GoRouter-Api/src/main/java/com/wyjson/router/service/ServiceHelper.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.wyjson.router.service; - -import androidx.annotation.Nullable; - -import com.wyjson.router.core.GoRouter; -import com.wyjson.router.exception.RouterException; -import com.wyjson.router.interfaces.IService; - -import java.util.HashMap; -import java.util.Map; - -public class ServiceHelper { - - private ServiceHelper() { - } - - private static class InstanceHolder { - private static final ServiceHelper mInstance = new ServiceHelper(); - } - - public static ServiceHelper getInstance() { - return InstanceHolder.mInstance; - } - - private static final Map, ServiceMeta> services = new HashMap<>(); - - public Map, ServiceMeta> getServices() { - return services; - } - - /** - * 实现相同接口的service会被覆盖(更新) - * 调用时机可以在application或插件模块加载时 - * - * @param serviceClass 实现类.class - */ - public void addService(Class serviceClass) { - Class serviceInterfaceClass = (Class) serviceClass.getInterfaces()[0]; - services.put(serviceInterfaceClass, new ServiceMeta(serviceClass)); - GoRouter.logger.debug(null, "[addService] size:" + services.size() + ", " + serviceInterfaceClass.getSimpleName() + " -> " + serviceClass.getSimpleName()); - } - - /** - * 获取service接口的实现 - * - * @param serviceClass 接口.class - * @param - * @return - */ - @Nullable - public T getService(Class serviceClass) { - ServiceMeta meta = services.get(serviceClass); - if (meta != null) { - if (serviceClass.isAssignableFrom(meta.getServiceClass())) { - IService instance = meta.getService(); - if (instance == null) { - try { - instance = meta.getServiceClass().getConstructor().newInstance(); - instance.init(); - meta.setService(instance); - } catch (Exception e) { - e.printStackTrace(); - throw new RouterException("serviceClass constructor new instance failed!"); - } - } - GoRouter.logger.info(null, "[getService] " + serviceClass.getSimpleName() + " -> " + meta.getServiceClass().getSimpleName()); - return (T) instance; - } - } - GoRouter.logger.warning(null, "[getService] " + serviceClass.getSimpleName() + ", No registered service found!"); - return null; - } -} \ No newline at end of file diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/thread/DefaultPoolExecutor.java b/GoRouter-Api/src/main/java/com/wyjson/router/thread/DefaultPoolExecutor.java index 4c0b258..ae5dab3 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/thread/DefaultPoolExecutor.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/thread/DefaultPoolExecutor.java @@ -1,6 +1,6 @@ package com.wyjson.router.thread; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; import com.wyjson.router.utils.TextUtils; import java.util.concurrent.ArrayBlockingQueue; diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/thread/DefaultThreadFactory.java b/GoRouter-Api/src/main/java/com/wyjson/router/thread/DefaultThreadFactory.java index 5f740b3..2a02bbc 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/thread/DefaultThreadFactory.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/thread/DefaultThreadFactory.java @@ -1,7 +1,7 @@ package com.wyjson.router.thread; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/utils/ClassUtils.java b/GoRouter-Api/src/main/java/com/wyjson/router/utils/ClassUtils.java index 03b414c..dde25f2 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/utils/ClassUtils.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/utils/ClassUtils.java @@ -6,7 +6,7 @@ import android.content.pm.PackageManager; import android.os.Build; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; import com.wyjson.router.thread.DefaultPoolExecutor; import java.io.File; @@ -48,9 +48,13 @@ private static SharedPreferences getMultiDexPreferences(Context context) { * * @param context * @param packageName 包名 + * @param nameSuffix * @return 所有class的集合 + * @throws PackageManager.NameNotFoundException + * @throws IOException + * @throws InterruptedException */ - public static Set getFileNameByPackageName(Context context, final String packageName) throws PackageManager.NameNotFoundException, IOException, InterruptedException { + public static Set getFileNameByPackageName(Context context, final String packageName, final String nameSuffix) throws PackageManager.NameNotFoundException, IOException, InterruptedException { final Set classNames = new HashSet<>(); List paths = getSourcePaths(context); @@ -73,7 +77,7 @@ public void run() { Enumeration dexEntries = dexfile.entries(); while (dexEntries.hasMoreElements()) { String className = dexEntries.nextElement(); - if (className.startsWith(packageName)) { + if (className.startsWith(packageName) && className.endsWith(nameSuffix)) { classNames.add(className); } } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorTreeMap.java b/GoRouter-Api/src/main/java/com/wyjson/router/utils/InterceptorTreeMap.java similarity index 94% rename from GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorTreeMap.java rename to GoRouter-Api/src/main/java/com/wyjson/router/utils/InterceptorTreeMap.java index 7b7ac07..3e6cad8 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interceptor/InterceptorTreeMap.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/utils/InterceptorTreeMap.java @@ -1,8 +1,8 @@ -package com.wyjson.router.interceptor; +package com.wyjson.router.utils; import androidx.annotation.NonNull; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; import com.wyjson.router.exception.RouterException; import java.util.Iterator; diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/utils/PackageUtils.java b/GoRouter-Api/src/main/java/com/wyjson/router/utils/PackageUtils.java index 558e970..d8ab92f 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/utils/PackageUtils.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/utils/PackageUtils.java @@ -1,13 +1,13 @@ package com.wyjson.router.utils; -import static com.wyjson.router.load.RouteModuleLoadUtils.GOROUTER_SP_CACHE_KEY; +import static com.wyjson.router.core.RouteModuleLoadCenter.GOROUTER_SP_CACHE_KEY; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; public class PackageUtils { diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/BaseProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/BaseProcessor.java index bab9085..1d0a6d9 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/BaseProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/BaseProcessor.java @@ -55,7 +55,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) { logger.info(moduleName + " The user has configuration the module name, it was [" + moduleName + "]"); } else { logger.error(NO_MODULE_NAME_TIPS); - throw new RuntimeException(PREFIX_OF_LOGGER + ">>> No module name, for more information, look at gradle log."); + throw new RuntimeException(PREFIX_OF_LOGGER + "No module name, for more information, look at gradle log."); } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index c334e19..ac53d9b 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -9,7 +9,6 @@ import static com.wyjson.router.compiler.utils.Constants.CHAR_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.DOUBEL_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.DOUBEL_PRIMITIVE; -import static com.wyjson.router.compiler.utils.Constants.FIELD_NAME_ROUTE_GROUPS; import static com.wyjson.router.compiler.utils.Constants.FLOAT_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.FLOAT_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.FRAGMENT; @@ -19,12 +18,15 @@ import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD; import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_GROUP_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_PACKAGE_NAME; +import static com.wyjson.router.compiler.utils.Constants.LOGISTICS_CENTER_METHOD_NAME_GET_ROUTE_GROUPS; +import static com.wyjson.router.compiler.utils.Constants.LOGISTICS_CENTER_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.LONG_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.LONG_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_GROUP; import static com.wyjson.router.compiler.utils.Constants.MODULE_PACKAGE_NAME; +import static com.wyjson.router.compiler.utils.Constants.PARAM_NAME_ROUTE_GROUPS; import static com.wyjson.router.compiler.utils.Constants.PARCELABLE_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.PREFIX_OF_LOGGER; import static com.wyjson.router.compiler.utils.Constants.PROJECT; @@ -40,9 +42,9 @@ import com.google.auto.service.AutoService; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; import com.wyjson.router.annotation.Interceptor; @@ -66,7 +68,6 @@ import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; @@ -76,6 +77,8 @@ public class GenerateModuleRouteProcessor extends BaseProcessor { TypeElement mGoRouter; TypeElement mIRouteModule; + + TypeElement mLogisticsCenter; TypeElement mIRouteModuleGroup; TypeMirror serializableType; TypeMirror parcelableType; @@ -99,11 +102,6 @@ public synchronized void init(ProcessingEnvironment processingEnv) { logger.info(moduleName + " >>> GenerateModuleRouteProcessor init. <<<"); mGoRouter = elementUtils.getTypeElement(GOROUTER_PACKAGE_NAME); mIRouteModule = elementUtils.getTypeElement(I_ROUTE_MODULE_PACKAGE_NAME); - mIRouteModuleGroup = elementUtils.getTypeElement(I_ROUTE_MODULE_GROUP_PACKAGE_NAME); - serializableType = elementUtils.getTypeElement(SERIALIZABLE_PACKAGE).asType(); - parcelableType = elementUtils.getTypeElement(PARCELABLE_PACKAGE).asType(); - activityType = elementUtils.getTypeElement(ACTIVITY).asType(); - fragmentType = elementUtils.getTypeElement(FRAGMENT).asType(); } @Override @@ -114,10 +112,6 @@ public boolean process(Set set, RoundEnvironment roundEnv DocumentUtils.createDoc(mFiler, moduleName, logger, isGenerateDoc); String className = generateClassName + SEPARATOR + PROJECT; - TypeSpec.Builder thisClass = TypeSpec.classBuilder(className) - .addModifiers(PUBLIC) - .addSuperinterface(ClassName.get(mIRouteModule)) - .addJavadoc(WARNING_TIPS); MethodSpec.Builder loadIntoMethod = MethodSpec.methodBuilder(METHOD_NAME_LOAD) .addModifiers(PUBLIC) @@ -126,11 +120,17 @@ public boolean process(Set set, RoundEnvironment roundEnv addService(roundEnvironment, loadIntoMethod); addInterceptor(roundEnvironment, loadIntoMethod); - LinkedHashSet routeGroupMethods = addRouteGroup(roundEnvironment, thisClass, loadIntoMethod); + LinkedHashSet routeGroupMethods = addRouteGroup(roundEnvironment, loadIntoMethod); - thisClass.addMethod(loadIntoMethod.build()).addMethods(routeGroupMethods); try { - JavaFile.builder(MODULE_PACKAGE_NAME, thisClass.build()) + JavaFile.builder(MODULE_PACKAGE_NAME, + TypeSpec.classBuilder(className) + .addModifiers(PUBLIC) + .addSuperinterface(ClassName.get(mIRouteModule)) + .addJavadoc(WARNING_TIPS) + .addMethod(loadIntoMethod.build()) + .addMethods(routeGroupMethods) + .build()) .indent(" ") .build() .writeTo(mFiler); @@ -172,7 +172,7 @@ private void addInterceptor(RoundEnvironment roundEnvironment, MethodSpec.Builde } } - private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironment, TypeSpec.Builder thisClass, MethodSpec.Builder loadIntoMethod) { + private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironment, MethodSpec.Builder loadIntoMethod) { LinkedHashSet routeGroupMethods = new LinkedHashSet<>(); Set elements = roundEnvironment.getElementsAnnotatedWith(Route.class); @@ -180,23 +180,27 @@ private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironmen return routeGroupMethods; logger.info(moduleName + " >>> Found Route, size is " + elements.size() + " <<<"); - FieldSpec routeGroupsField = FieldSpec.builder( - ParameterizedTypeName.get( - ClassName.get(Map.class), - ClassName.get(String.class), - ClassName.get(mIRouteModuleGroup) - ), - FIELD_NAME_ROUTE_GROUPS, - Modifier.PRIVATE, - Modifier.FINAL - ) - .initializer("new $T<>()", ClassName.get(HashMap.class)) - .build(); - thisClass.addField(routeGroupsField); - - MethodSpec.Builder loadRouteGroupMethod = MethodSpec.methodBuilder(METHOD_NAME_LOAD_ROUTE_GROUP).addModifiers(PRIVATE); + mLogisticsCenter = elementUtils.getTypeElement(LOGISTICS_CENTER_PACKAGE_NAME); + mIRouteModuleGroup = elementUtils.getTypeElement(I_ROUTE_MODULE_GROUP_PACKAGE_NAME); + serializableType = elementUtils.getTypeElement(SERIALIZABLE_PACKAGE).asType(); + parcelableType = elementUtils.getTypeElement(PARCELABLE_PACKAGE).asType(); + activityType = elementUtils.getTypeElement(ACTIVITY).asType(); + fragmentType = elementUtils.getTypeElement(FRAGMENT).asType(); + + ParameterSpec routeGroupsParamSpec = ParameterSpec.builder( + ParameterizedTypeName.get( + ClassName.get(Map.class), + ClassName.get(String.class), + ClassName.get(mIRouteModuleGroup) + ), + PARAM_NAME_ROUTE_GROUPS + ).build(); + + MethodSpec.Builder loadRouteGroupMethod = MethodSpec + .methodBuilder(METHOD_NAME_LOAD_ROUTE_GROUP) + .addModifiers(PRIVATE) + .addParameter(routeGroupsParamSpec); loadRouteGroupMethod.addJavadoc("load route group"); - loadRouteGroupMethod.addStatement("$N.clear()", routeGroupsField); saveRouteGroup(elements); @@ -223,13 +227,15 @@ private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironmen iRouteModuleGroupCode.add("}"); CodeBlock.Builder routeGroupPutCode = CodeBlock.builder(); - routeGroupPutCode.add("$N.put($S, $N)", routeGroupsField, groupName, iRouteModuleGroupCode.build().toString()); + routeGroupPutCode.add("$N.put($S, $N)", routeGroupsParamSpec, groupName, iRouteModuleGroupCode.build().toString()); + loadRouteGroupMethod.addStatement(routeGroupPutCode.build()); } loadIntoMethod.addCode("// call load route group\n"); - loadIntoMethod.addStatement("$N()", loadRouteGroupMethod.build()); + + loadIntoMethod.addStatement("$N($T.$N())", loadRouteGroupMethod.build(), mLogisticsCenter, LOGISTICS_CENTER_METHOD_NAME_GET_ROUTE_GROUPS); routeGroupMethods.add(loadRouteGroupMethod.build()); return routeGroupMethods; } @@ -259,7 +265,7 @@ public int compare(Element r1, Element r2) { private String extractRouteGroup(String path) { if (StringUtils.isEmpty(path) || !path.startsWith("/")) { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Extract the path[" + path + "] group failed, Extract the default group failed, the path must be start with '/' and contain more than 2 '/'!"); + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Extract the path[" + path + "] group failed, Extract the default group failed, the path must be start with '/' and contain more than 2 '/'!"); } try { String group = path.substring(1, path.indexOf("/", 1)); @@ -268,7 +274,7 @@ private String extractRouteGroup(String path) { } return group; } catch (Exception e) { - throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Failed to extract path[" + path + "] group! " + e.getMessage()); + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Extract the path[" + path + "] group failed, Extract the default group failed, the path must be start with '/' and contain more than 2 '/'! " + e.getMessage()); } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java index 49ea391..aa32281 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java @@ -5,23 +5,28 @@ public class Constants { public static final String PROJECT = "GoRouter"; public static final String SEPARATOR = "$$"; public static final String WARNING_TIPS = "DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY GOROUTER."; - public static final String METHOD_NAME_LOAD = "load"; - public static final String METHOD_NAME_LOAD_ROUTE_GROUP = "loadRouteGroup"; - public static final String METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP = "loadRouteFor%sGroup"; - public static final String FIELD_NAME_ROUTE_GROUPS = "routeGroups"; // System interface public static final String ACTIVITY = "android.app.Activity"; public static final String FRAGMENT = "androidx.fragment.app.Fragment"; public static final String PACKAGE_NAME = "com.wyjson.router"; - public static final String MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module"; public static final String DOCS_PACKAGE_NAME = PACKAGE_NAME + ".docs"; - public static final String GOROUTER_PACKAGE_NAME = PACKAGE_NAME + ".core.GoRouter"; - public static final String I_ROUTE_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".load.IRouteModule"; - public static final String I_ROUTE_MODULE_GROUP_PACKAGE_NAME = PACKAGE_NAME + ".load.IRouteModuleGroup"; + public static final String GOROUTER_PACKAGE_NAME = PACKAGE_NAME + ".GoRouter"; + + public static final String MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module"; + public static final String I_ROUTE_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module.interfaces.IRouteModule"; + public static final String METHOD_NAME_LOAD = "load"; + public static final String METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP = "loadRouteFor%sGroup"; + public static final String METHOD_NAME_LOAD_ROUTE_GROUP = "loadRouteGroup"; + public static final String PARAM_NAME_ROUTE_GROUPS = "routeGroups"; + + public static final String I_ROUTE_MODULE_GROUP_PACKAGE_NAME = PACKAGE_NAME + ".module.interfaces.IRouteModuleGroup"; public static final String I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD = "load"; + public static final String LOGISTICS_CENTER_PACKAGE_NAME = PACKAGE_NAME + ".core.LogisticsCenter"; + public static final String LOGISTICS_CENTER_METHOD_NAME_GET_ROUTE_GROUPS = "getRouteGroups"; + // Log public static final String PREFIX_OF_LOGGER = PROJECT + "::Compiler "; public static final String NO_MODULE_NAME_TIPS = """ diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteTask.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteTask.kt index fcb0cda..550a402 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteTask.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteTask.kt @@ -2,6 +2,7 @@ package com.wyjson.router.gradle_plugin.core import com.wyjson.router.gradle_plugin.utils.Constants import com.wyjson.router.gradle_plugin.utils.Constants.INJECT_CLASS_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.MODULE_ROUTE_NAME_SUFFIX import com.wyjson.router.gradle_plugin.utils.Constants.SCAN_TARGET_INJECT_PACKAGE_NAME import com.wyjson.router.gradle_plugin.utils.Constants._CLASS import com.wyjson.router.gradle_plugin.utils.Logger @@ -61,8 +62,8 @@ abstract class AssembleModuleRouteTask : DefaultTask() { // Logger.i("Scan to directory [${directory.asFile.absolutePath}]") directory.asFile.walk().forEach { file -> if (file.isFile) { - if (file.name.endsWith(Constants.MODULE_ROUTE_NAME_SUFFIX)) { - Logger.i("Scan to class [${file.name}] be from directory [${directory.asFile.absolutePath}]") + if (file.name.endsWith(MODULE_ROUTE_NAME_SUFFIX + _CLASS)) { + Logger.i("Scan to class [${file.name}] be from directory [${directory.asFile.absolutePath}]") moduleRouteClassList.add(file.name) } val relativePath = directory.asFile.toURI().relativize(file.toURI()).path @@ -96,7 +97,8 @@ abstract class AssembleModuleRouteTask : DefaultTask() { } } else { val startsWith = entryName.startsWith(Constants.dotToSlash(SCAN_TARGET_INJECT_PACKAGE_NAME)) - if (startsWith) { + val endsWith = entryName.endsWith(Constants.dotToSlash(MODULE_ROUTE_NAME_SUFFIX) + _CLASS) + if (startsWith && endsWith) { val className = entryName.substring(entryName.lastIndexOf("/") + 1) Logger.i("Scan to class [$className] be from jar [${file.asFile.absolutePath}]") if (className.isNotEmpty()) { diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt index 6486f3b..09642ba 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt @@ -8,14 +8,14 @@ object Constants { const val PROJECT = "GoRouter"; const val _CLASS = ".class" - // 路由注册生成类名后缀$$GoRouter.class - const val MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "GoRouter" + _CLASS + // 路由注册生成类名后缀$$GoRouter + const val MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "GoRouter" // 需要扫描注入的类,所在的包名 const val SCAN_TARGET_INJECT_PACKAGE_NAME = "$PACKAGE_NAME.module" // 注入到这个类下 - const val INJECT_CLASS_NAME = "$PACKAGE_NAME.load.RouteModuleLoadUtils" + const val INJECT_CLASS_NAME = "$PACKAGE_NAME.core.RouteModuleLoadCenter" // 注入到这个方法 const val INJECT_METHOD_NAME = "loadModuleRouteByPlugin" diff --git a/README.md b/README.md index cd3868f..3e37015 100644 --- a/README.md +++ b/README.md @@ -565,14 +565,16 @@ GoRouter日志tag为`GoRouter`,GoRouter-Compiler日志tag为`GoRouter::Compile ##### 6. ARouter迁移指南 -| ARouter | GoRouter | -| ------------------ | ---------- | -| ARouter | GoRouter | -| navigation() | go() | -| NavigationCallback | GoCallback | -| IProvider | IService | -| Postcard | Card | -| @Route | @Route | -| @Route | @Service | -| @Route | @Interceptor | -| @Autowired | @Param | +| ARouter | GoRouter | +| ------------------- | -------------------- | +| ARouter | GoRouter | +| navigation() | go() | +| NavigationCallback | GoCallback | +| IProvider | IService | +| DegradeService | IDegradeService | +| PretreatmentService | IPretreatmentService | +| Postcard | Card | +| @Route | @Route | +| @Route | @Service | +| @Route | @Interceptor | +| @Autowired | @Param | diff --git a/app/src/main/java/com/wyjson/go_router/MyApplication.java b/app/src/main/java/com/wyjson/go_router/MyApplication.java index d099dc2..acccdcc 100644 --- a/app/src/main/java/com/wyjson/go_router/MyApplication.java +++ b/app/src/main/java/com/wyjson/go_router/MyApplication.java @@ -3,7 +3,7 @@ import android.app.Application; import com.wyjson.module_common.BuildConfig; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; public class MyApplication extends Application { diff --git a/module_common/src/main/java/com/wyjson/module_common/route/service/DegradeServiceImpl.java b/module_common/src/main/java/com/wyjson/module_common/route/service/DegradeServiceImpl.java index 5c35cdf..3325ac3 100644 --- a/module_common/src/main/java/com/wyjson/module_common/route/service/DegradeServiceImpl.java +++ b/module_common/src/main/java/com/wyjson/module_common/route/service/DegradeServiceImpl.java @@ -4,11 +4,11 @@ import android.widget.Toast; import com.wyjson.router.annotation.Service; -import com.wyjson.router.card.Card; -import com.wyjson.router.interfaces.DegradeService; +import com.wyjson.router.model.Card; +import com.wyjson.router.interfaces.IDegradeService; @Service(remark = "全局降级策略") -public class DegradeServiceImpl implements DegradeService { +public class DegradeServiceImpl implements IDegradeService { @Override public void onLost(Context context, Card card) { diff --git a/module_common/src/main/java/com/wyjson/module_common/route/service/PretreatmentServiceImpl.java b/module_common/src/main/java/com/wyjson/module_common/route/service/PretreatmentServiceImpl.java index de3c4cf..af1b441 100644 --- a/module_common/src/main/java/com/wyjson/module_common/route/service/PretreatmentServiceImpl.java +++ b/module_common/src/main/java/com/wyjson/module_common/route/service/PretreatmentServiceImpl.java @@ -5,11 +5,11 @@ import com.wyjson.module_common.route.UserRoute; import com.wyjson.router.annotation.Service; -import com.wyjson.router.card.Card; -import com.wyjson.router.interfaces.PretreatmentService; +import com.wyjson.router.model.Card; +import com.wyjson.router.interfaces.IPretreatmentService; @Service(remark = "预处理服务") -public class PretreatmentServiceImpl implements PretreatmentService { +public class PretreatmentServiceImpl implements IPretreatmentService { @Override public void init() { diff --git a/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java b/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java index bedefe6..49d3b07 100644 --- a/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java +++ b/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java @@ -18,8 +18,8 @@ import com.wyjson.module_main.databinding.MainActivityMainBinding; import com.wyjson.router.annotation.Route; import com.wyjson.router.callback.GoCallback; -import com.wyjson.router.card.Card; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.model.Card; +import com.wyjson.router.GoRouter; @Route(path = MainRoute.MainActivity, remark = "主页") public class MainActivity extends FragmentActivity { diff --git a/module_main/src/main/java/com/wyjson/module_main/activity/SplashActivity.java b/module_main/src/main/java/com/wyjson/module_main/activity/SplashActivity.java index 2cd014f..db1682a 100755 --- a/module_main/src/main/java/com/wyjson/module_main/activity/SplashActivity.java +++ b/module_main/src/main/java/com/wyjson/module_main/activity/SplashActivity.java @@ -4,9 +4,9 @@ import com.wyjson.module_common.route.MainRoute; import com.wyjson.router.annotation.Route; -import com.wyjson.router.callback.GoCallbackImpl; -import com.wyjson.router.card.Card; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.callback.impl.GoCallbackImpl; +import com.wyjson.router.model.Card; +import com.wyjson.router.GoRouter; @Route(path = MainRoute.SplashActivity, remark = "欢迎页") public class SplashActivity extends FragmentActivity { diff --git a/module_user/src/main/java/com/wyjson/module_user/activity/ParamActivity.java b/module_user/src/main/java/com/wyjson/module_user/activity/ParamActivity.java index c7ac512..b701071 100644 --- a/module_user/src/main/java/com/wyjson/module_user/activity/ParamActivity.java +++ b/module_user/src/main/java/com/wyjson/module_user/activity/ParamActivity.java @@ -9,7 +9,7 @@ import com.wyjson.module_user.databinding.UserActivityParamBinding; import com.wyjson.router.annotation.Param; import com.wyjson.router.annotation.Route; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; @Route(path = UserRoute.ParamActivity, remark = "参数页面") public class ParamActivity extends BaseParamActivity { diff --git a/module_user/src/main/java/com/wyjson/module_user/fragment/ParamFragment.java b/module_user/src/main/java/com/wyjson/module_user/fragment/ParamFragment.java index 5618469..a917549 100644 --- a/module_user/src/main/java/com/wyjson/module_user/fragment/ParamFragment.java +++ b/module_user/src/main/java/com/wyjson/module_user/fragment/ParamFragment.java @@ -13,7 +13,7 @@ import com.wyjson.module_user.databinding.UserFragmentParamBinding; import com.wyjson.router.annotation.Param; import com.wyjson.router.annotation.Route; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.GoRouter; @Route(path = UserRoute.ParamFragment, remark = "参数片段") public class ParamFragment extends Fragment { diff --git a/module_user/src/main/java/com/wyjson/module_user/route/interceptor/AuthenticationInterceptor.java b/module_user/src/main/java/com/wyjson/module_user/route/interceptor/AuthenticationInterceptor.java index b787d03..d9ba395 100644 --- a/module_user/src/main/java/com/wyjson/module_user/route/interceptor/AuthenticationInterceptor.java +++ b/module_user/src/main/java/com/wyjson/module_user/route/interceptor/AuthenticationInterceptor.java @@ -4,9 +4,9 @@ import com.wyjson.module_common.route.utils.RouteTagUtils; import com.wyjson.router.annotation.Interceptor; -import com.wyjson.router.card.Card; +import com.wyjson.router.model.Card; import com.wyjson.router.exception.RouterException; -import com.wyjson.router.interceptor.InterceptorCallback; +import com.wyjson.router.callback.InterceptorCallback; import com.wyjson.router.interfaces.IInterceptor; @Interceptor(priority = 100, remark = "身份验证拦截器") diff --git a/module_user/src/main/java/com/wyjson/module_user/route/interceptor/SignInInterceptor.java b/module_user/src/main/java/com/wyjson/module_user/route/interceptor/SignInInterceptor.java index b4be80a..300bef9 100644 --- a/module_user/src/main/java/com/wyjson/module_user/route/interceptor/SignInInterceptor.java +++ b/module_user/src/main/java/com/wyjson/module_user/route/interceptor/SignInInterceptor.java @@ -2,7 +2,6 @@ import static com.wyjson.module_common.route.BaseRoute.IS_LOGIN; -import android.content.DialogInterface; import android.os.Handler; import android.os.Looper; @@ -11,10 +10,10 @@ import com.wyjson.module_common.route.UserRoute; import com.wyjson.module_common.route.utils.RouteTagUtils; import com.wyjson.router.annotation.Interceptor; -import com.wyjson.router.card.Card; -import com.wyjson.router.core.GoRouter; +import com.wyjson.router.model.Card; +import com.wyjson.router.GoRouter; import com.wyjson.router.exception.RouterException; -import com.wyjson.router.interceptor.InterceptorCallback; +import com.wyjson.router.callback.InterceptorCallback; import com.wyjson.router.interfaces.IInterceptor; @Interceptor(priority = 1, remark = "登录拦截器") diff --git a/settings.gradle b/settings.gradle index 78af213..f9fa1c6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,6 @@ pluginManagement { repositories { -// mavenLocal() + mavenLocal() maven { url 'https://jitpack.io' } google() mavenCentral() From b8f6318dca1b6f94a3eda23335cf9e0c7af5df1e Mon Sep 17 00:00:00 2001 From: Wyjson Date: Fri, 10 Nov 2023 19:06:44 +0800 Subject: [PATCH 09/28] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=88=86=E7=BB=84:?= =?UTF-8?q?=E5=8F=91=E7=8E=B0=E5=B7=B2=E7=BB=8F=E5=AD=98=E5=9C=A8=E7=9A=84?= =?UTF-8?q?=E5=88=86=E7=BB=84,=E7=9B=B4=E6=8E=A5=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E5=88=86=E7=BB=84=E9=87=8C=E7=9A=84=E5=8A=A0=E8=BD=BD=E6=96=B9?= =?UTF-8?q?=E6=B3=95,=E5=86=8D=E6=B7=BB=E5=8A=A0=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E6=95=B0=E6=8D=AE=E8=BF=9B=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GoRouter-Api/consumer-rules.pro | 13 +++++++++ .../wyjson/router/core/LogisticsCenter.java | 2 +- .../com/wyjson/router/core/Warehouse.java | 3 +- .../router/utils/InterceptorTreeMap.java | 4 +-- .../router/utils/RouteGroupHashMap.java | 28 +++++++++++++++++++ app/proguard-rules.pro | 11 +------- 6 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/utils/RouteGroupHashMap.java diff --git a/GoRouter-Api/consumer-rules.pro b/GoRouter-Api/consumer-rules.pro index 739a488..f36a3da 100644 --- a/GoRouter-Api/consumer-rules.pro +++ b/GoRouter-Api/consumer-rules.pro @@ -6,4 +6,17 @@ } # 自动注册模块路由加载类不混淆 -keep class * implements com.wyjson.router.module.interfaces.IRouteModule +# # ########## GoRouter # end ########## + + +# # ########## delete GoRouter logger # start ########## +# 1.使用混淆优化文件 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' +# 2.不开启 -dontoptimize +# 3.满足以上两点下面的配置才会生效 +-assumenosideeffects class com.wyjson.router.logger.DefaultLogger { + public *** debug(...); + public *** info(...); + public *** warning(...); + public *** error(...); +} # # ########## GoRouter # end ########## \ No newline at end of file diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java index 581df5f..df5d32a 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java @@ -55,7 +55,7 @@ public static CardMeta getCardMeta(Card card) throws NoFoundRouteException { GoRouter.logger.debug(null, "[getCardMeta] The group [" + card.getGroup() + "] has already been loaded, trigger by [" + card.getPath() + "]"); } } catch (Exception e) { - throw new RouterException("Fatal exception when loading group meta. [" + e.getMessage() + "]"); + throw new RouterException("Fatal exception when loading route group[" + card.getGroup() + "] meta. [" + e.getMessage() + "]"); } return getCardMeta(card);// Reload } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java index 739d709..aa46a1e 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java @@ -6,13 +6,14 @@ import com.wyjson.router.model.ServiceMeta; import com.wyjson.router.module.interfaces.IRouteModuleGroup; import com.wyjson.router.utils.InterceptorTreeMap; +import com.wyjson.router.utils.RouteGroupHashMap; import java.util.HashMap; import java.util.Map; class Warehouse { - static final Map routeGroups = new HashMap<>(); + static final Map routeGroups = new RouteGroupHashMap(); static final Map routes = new HashMap<>(); static final Map, ServiceMeta> services = new HashMap<>(); diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/utils/InterceptorTreeMap.java b/GoRouter-Api/src/main/java/com/wyjson/router/utils/InterceptorTreeMap.java index 3e6cad8..6be7e20 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/utils/InterceptorTreeMap.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/utils/InterceptorTreeMap.java @@ -47,9 +47,9 @@ public String toString() { Entry e = i.next(); K key = e.getKey(); V value = e.getValue(); - sb.append(key == this ? "(this Map)" : key); + sb.append(key); sb.append("->"); - sb.append(value == this ? "(this Map)" : value.getClass().getSimpleName()); + sb.append(value.getClass().getSimpleName()); if (!i.hasNext()) return sb.append('}').toString(); sb.append(',').append(' '); diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/utils/RouteGroupHashMap.java b/GoRouter-Api/src/main/java/com/wyjson/router/utils/RouteGroupHashMap.java new file mode 100644 index 0000000..bad9200 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/utils/RouteGroupHashMap.java @@ -0,0 +1,28 @@ +package com.wyjson.router.utils; + +import androidx.annotation.Nullable; + +import com.wyjson.router.GoRouter; +import com.wyjson.router.exception.RouterException; +import com.wyjson.router.module.interfaces.IRouteModuleGroup; + +import java.util.HashMap; + +public class RouteGroupHashMap extends HashMap { + + @Nullable + @Override + public IRouteModuleGroup put(String key, IRouteModuleGroup value) { + // 发现已经存在的分组,直接执行分组里的加载方法,再添加新的路由数据进来 + if (containsKey(key)) { + try { + GoRouter.logger.warning(null, "Discover an existing group[" + key + "], execute the loading method in the group, and add new route data."); + get(key).load(); + } catch (Exception e) { + throw new RouterException("A fatal exception occurred while loading the route group[" + key + "]. [" + e.getMessage() + "]"); + } + } + return super.put(key, value); + } + +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index bc6258f..cc62e4d 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -76,16 +76,7 @@ # # ########## WebView # end ########## -# # ########## GoRouter # start ########## -# 删除GoRouter logger -# 需要删除-dontoptimize --assumenosideeffects class com.wyjson.router.logger.DefaultLogger { - public *** debug(...); - public *** info(...); - public *** warning(...); - public *** error(...); -} -# # ########## GoRouter # end ########## + From 8d6a8d88a3303aff657c4d4d381dac3d5bafe0a0 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Fri, 10 Nov 2023 19:16:35 +0800 Subject: [PATCH 10/28] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=B7=AF=E7=94=B1=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/wyjson/router/GoRouter.java | 16 +++++++++++++++- .../module_main/activity/MainActivity.java | 10 ++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java index eed8ba4..3171e48 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java @@ -22,6 +22,7 @@ import com.wyjson.router.core.LogisticsCenter; import com.wyjson.router.core.RouteModuleLoadCenter; import com.wyjson.router.core.interfaces.IInterceptorService; +import com.wyjson.router.enums.RouteType; import com.wyjson.router.exception.NoFoundRouteException; import com.wyjson.router.exception.RouterException; import com.wyjson.router.interfaces.IDegradeService; @@ -31,9 +32,11 @@ import com.wyjson.router.logger.DefaultLogger; import com.wyjson.router.logger.ILogger; import com.wyjson.router.model.Card; +import com.wyjson.router.module.interfaces.IRouteModuleGroup; import com.wyjson.router.thread.DefaultPoolExecutor; import com.wyjson.router.utils.TextUtils; +import java.util.Map; import java.util.concurrent.ThreadPoolExecutor; public final class GoRouter { @@ -151,6 +154,18 @@ public void setInterceptor(int priority, Class intercept LogisticsCenter.setInterceptor(priority, interceptor); } + /** + * 动态添加路由分组 + */ + public void addRouterGroup(Function function) { + // TODO: 2023/11/10 :::未完成 + function.apply(LogisticsCenter.getRouteGroups()); + } + + public interface Function { + void apply(Map t); + } + private void runInMainThread(Runnable runnable) { if (Looper.getMainLooper().getThread() != Thread.currentThread()) { mHandler.post(runnable); @@ -195,7 +210,6 @@ public void inject(Fragment fragment, Bundle bundle) { LogisticsCenter.inject(fragment, null, bundle); } - @Nullable public Object go(Context context, Card card, int requestCode, GoCallback callback) { card.setContext(context); diff --git a/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java b/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java index 49d3b07..0f3a679 100644 --- a/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java +++ b/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java @@ -20,6 +20,9 @@ import com.wyjson.router.callback.GoCallback; import com.wyjson.router.model.Card; import com.wyjson.router.GoRouter; +import com.wyjson.router.module.interfaces.IRouteModuleGroup; + +import java.util.Map; @Route(path = MainRoute.MainActivity, remark = "主页") public class MainActivity extends FragmentActivity { @@ -36,6 +39,13 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { public void onClickSignInActivity(View view) { GoRouter.getInstance().build(UserRoute.SignInActivity).go(this); + // TODO: 2023/11/10 :::Test 动态添加路由分组 + GoRouter.getInstance().addRouterGroup(new GoRouter.Function() { + @Override + public void apply(Map t) { + + } + }); } public void onClickParamActivity(View view) { From 0aefef7f188d74eb43c63ff3b32205b43f299db6 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Fri, 10 Nov 2023 21:49:52 +0800 Subject: [PATCH 11/28] =?UTF-8?q?=E5=8D=87=E7=BA=A7gradle8.1.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GoRouter-Gradle-Plugin/build.gradle | 2 +- build.gradle | 4 ++-- gradle.properties | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/GoRouter-Gradle-Plugin/build.gradle b/GoRouter-Gradle-Plugin/build.gradle index 95e2f21..0a40b2f 100644 --- a/GoRouter-Gradle-Plugin/build.gradle +++ b/GoRouter-Gradle-Plugin/build.gradle @@ -11,7 +11,7 @@ java { dependencies { implementation gradleApi() implementation localGroovy() - implementation 'com.android.tools.build:gradle:8.0.0' + implementation 'com.android.tools.build:gradle:8.1.2' implementation 'org.ow2.asm:asm:9.2' implementation 'org.ow2.asm:asm-commons:9.2' } diff --git a/build.gradle b/build.gradle index a6ade8d..e98bfee 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { } plugins { - id 'com.android.application' version '8.0.0' apply false - id 'com.android.library' version '8.0.0' apply false + id 'com.android.application' version '8.1.2' apply false + id 'com.android.library' version '8.1.2' apply false id 'org.jetbrains.kotlin.jvm' version '1.9.0' apply false } diff --git a/gradle.properties b/gradle.properties index a845fcd..6d76f67 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,6 +20,8 @@ android.useAndroidX=true # thereby reducing the size of the R class for that library android.nonTransitiveRClass=true +org.gradle.unsafe.configuration-cache=true + # Debug APT # org.gradle.daemon=true # org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 From a530c1bf682f78971418f3b063c209640e4b6ce0 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sat, 11 Nov 2023 00:02:09 +0800 Subject: [PATCH 12/28] =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=88=86=E7=BB=84,=E6=8C=89=E9=9C=80?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/wyjson/router/GoRouter.java | 20 +++-------- .../wyjson/router/core/LogisticsCenter.java | 36 ++++++++++++++++--- .../module_main/activity/MainActivity.java | 12 +------ .../main/res/layout/main_activity_main.xml | 2 +- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java index 3171e48..b9dbe03 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java @@ -22,7 +22,6 @@ import com.wyjson.router.core.LogisticsCenter; import com.wyjson.router.core.RouteModuleLoadCenter; import com.wyjson.router.core.interfaces.IInterceptorService; -import com.wyjson.router.enums.RouteType; import com.wyjson.router.exception.NoFoundRouteException; import com.wyjson.router.exception.RouterException; import com.wyjson.router.interfaces.IDegradeService; @@ -36,7 +35,6 @@ import com.wyjson.router.thread.DefaultPoolExecutor; import com.wyjson.router.utils.TextUtils; -import java.util.Map; import java.util.concurrent.ThreadPoolExecutor; public final class GoRouter { @@ -112,7 +110,6 @@ public static void setLogger(ILogger userLogger) { /** * 实现相同接口的service会被覆盖(更新) - * 调用时机可以在application或插件模块加载时 * * @param service 实现类.class */ @@ -133,8 +130,7 @@ public T getService(Class service) { } /** - * 相同优先级添加会catch - * 调用时机可以在application或插件模块加载时 + * 重复添加相同优先级会catch * * @param priority * @param interceptor @@ -144,8 +140,7 @@ public void addInterceptor(int priority, Class intercept } /** - * 相同优先级添加会覆盖 - * 调用时机可以在application或插件模块加载时 + * 重复添加相同优先级会覆盖(更新) * * @param priority * @param interceptor @@ -155,15 +150,10 @@ public void setInterceptor(int priority, Class intercept } /** - * 动态添加路由分组 + * 动态添加路由分组,按需加载路由 */ - public void addRouterGroup(Function function) { - // TODO: 2023/11/10 :::未完成 - function.apply(LogisticsCenter.getRouteGroups()); - } - - public interface Function { - void apply(Map t); + public void addRouterGroup(String group, IRouteModuleGroup routeModuleGroup) { + LogisticsCenter.addRouterGroup(group, routeModuleGroup); } private void runInMainThread(Runnable runnable) { diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java index df5d32a..71e6d5c 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java @@ -32,6 +32,24 @@ public static Map getRouteGroups() { return Warehouse.routeGroups; } + /** + * 动态添加路由分组,按需加载路由 + * + * @param group + * @param routeModuleGroup + */ + public static void addRouterGroup(String group, IRouteModuleGroup routeModuleGroup) { + Warehouse.routeGroups.put(group, routeModuleGroup); + GoRouter.logger.info(null, "[addRouterGroup] Add a route group[" + group + "] dynamically"); + } + + /** + * 获取路由元数据 + * + * @param card + * @return + * @throws NoFoundRouteException + */ public static CardMeta getCardMeta(Card card) throws NoFoundRouteException { CardMeta cardMeta = Warehouse.routes.get(card.getPath()); if (cardMeta == null) { @@ -65,6 +83,11 @@ public static CardMeta getCardMeta(Card card) throws NoFoundRouteException { return cardMeta; } + /** + * 添加路由元数据 + * + * @param cardMeta + */ public static void addCardMeta(CardMeta cardMeta) { if (TextUtils.isEmpty(cardMeta.getPath())) { throw new RouterException("path Parameter is invalid!"); @@ -88,7 +111,6 @@ public static void addCardMeta(CardMeta cardMeta) { /** * 实现相同接口的service会被覆盖(更新) - * 调用时机可以在application或插件模块加载时 * * @param serviceClass 实现类.class */ @@ -130,8 +152,7 @@ public static T getService(Class serviceClass) { } /** - * 相同优先级添加会catch - * 调用时机可以在application或插件模块加载时 + * 重复添加相同优先级会catch * * @param priority * @param interceptor @@ -154,8 +175,7 @@ public static void addInterceptor(int priority, Class in } /** - * 相同优先级添加会覆盖 - * 调用时机可以在application或插件模块加载时 + * 重复添加相同优先级会覆盖(更新) * * @param priority * @param interceptor @@ -244,6 +264,12 @@ private static Field getDeclaredField(Class cls, String key) throws NoSuchFie } } + /** + * 组装路由原数组 + * + * @param card + * @throws NoFoundRouteException + */ public static synchronized void assembleRouteCard(@NonNull Card card) throws NoFoundRouteException { CardMeta cardMeta = getCardMeta(card); if (cardMeta != null) { diff --git a/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java b/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java index 0f3a679..315bc8c 100644 --- a/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java +++ b/module_main/src/main/java/com/wyjson/module_main/activity/MainActivity.java @@ -16,13 +16,10 @@ import com.wyjson.module_common.route.service.user.UserService; import com.wyjson.module_main.R; import com.wyjson.module_main.databinding.MainActivityMainBinding; +import com.wyjson.router.GoRouter; import com.wyjson.router.annotation.Route; import com.wyjson.router.callback.GoCallback; import com.wyjson.router.model.Card; -import com.wyjson.router.GoRouter; -import com.wyjson.router.module.interfaces.IRouteModuleGroup; - -import java.util.Map; @Route(path = MainRoute.MainActivity, remark = "主页") public class MainActivity extends FragmentActivity { @@ -39,13 +36,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { public void onClickSignInActivity(View view) { GoRouter.getInstance().build(UserRoute.SignInActivity).go(this); - // TODO: 2023/11/10 :::Test 动态添加路由分组 - GoRouter.getInstance().addRouterGroup(new GoRouter.Function() { - @Override - public void apply(Map t) { - - } - }); } public void onClickParamActivity(View view) { diff --git a/module_main/src/main/res/layout/main_activity_main.xml b/module_main/src/main/res/layout/main_activity_main.xml index 6c93026..c67c24d 100644 --- a/module_main/src/main/res/layout/main_activity_main.xml +++ b/module_main/src/main/res/layout/main_activity_main.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="#80ff0000" + android:background="#800000ff" android:orientation="vertical" tools:context=".activity.MainActivity"> From 10c303ff1de8666d554439064d1fd6c119e507c7 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sat, 11 Nov 2023 00:02:19 +0800 Subject: [PATCH 13/28] update README.md --- README.md | 114 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 3e37015..a140d48 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,21 @@ ## 简介 -之前一直在用阿里开源的[ARouter](https://github.com/alibaba/ARouter)项目,因为ARouter多年未更新,ARouter 开始有些不太适合了,所以重新开发了这款Android路由框架。 +之前一直在用阿里开源的[ARouter](https://github.com/alibaba/ARouter)项目,因为ARouter多年未更新,ARouter开始有些不太适合了,所以重新开发了这款Android路由框架,同样的API,更多的功能,迁移请参见文末6-7。 ## GoRouter和ARouter功能差异对比 -| 功能 | ARouter | GoRouter | 描述 | -| ------------ | ------- | -------- | ---------------------------------------------------- | -| 路由注册方式 | 注解 | 注解、java | GoRouter不仅提供了注解,还能使用java方式注册,参见5-6 | -| 服务 | 一对多 | 一对一 | ARouter可以为一个服务接口注册多个实现类(没啥用),本库一个服务接口对应一个实现方法(调用更方便) | -| 动态注册拦截器 | 不支持 | 支持 | ARouter只能动态注册路由,不能动态注册拦截器 | -| 重写跳转URL服务 | 支持 | 不支持 | 可以在`PretreatmentService`里实现相同功能 | -| 获取元数据 | 不支持 | 支持 | 有些场景需要判断某个页面当前是否存在,就需要获取页面class等信息,参见5-1 | -| withObject() | 支持 | 不支持 | ARouter实现原理是转JSON后使用`withString()`方法传递 | -| inject(T) | 单一 | 更多 | ARouter不能在`onNewIntent()`方法里使用,GoRouter提供了更多使用场景 | -| 按组分类、按需初始化 | 支持 | 不支持 | 待开发,对于路由页面多的项目有一定提升 | -| 模块Application生命周期 | 不支持 | 待开发 | 模块化路由都有了,肯定也需要模块Application生命周期,正好本库Api、生成类、自动注册都有,所以开发一下这个功能很方便 | +| 功能 | ARouter | GoRouter | 描述 | +| ---------------------- | -------- | --------- | ---------------------------------------------------- | +| 路由注册方式 | 注解 | 注解、java | GoRouter不仅提供了注解,还能使用java方式注册,参见5-6 | +| 服务 | 一对多 | 一对一 | ARouter可以为一个服务接口注册多个实现类(没啥用),本库一个服务接口对应一个实现方法(调用更方便) | +| 动态注册拦截器 | 不支持 | 支持 | ARouter只能动态注册路由,不能动态注册拦截器 | +| 重写跳转URL服务 | 支持 | 不支持 | 可以在`PretreatmentService`里实现相同功能 | +| 获取元数据 | 不支持 | 支持 | 有些场景需要判断某个页面当前是否存在等需求,就需要获取页面class等信息,参见5-1 | +| withObject() | 支持 | 不支持 | ARouter实现原理是转JSON后使用`withString()`方法传递 | +| inject(T) | 单一 | 更多 | ARouter不能在`onNewIntent()`方法里使用,GoRouter提供了更多使用场景 | +| 按组分类、按需初始化 | 支持 | 支持 | ARouter不允许多个module中存在相同的分组,GoRouter允许 | +| 多模块Application生命周期 | 不支持 | 待开发 | 模块化路由都有了,肯定也需要多模块Application生命周期,正好本库Api、注解处理器、自动注册都有,所以开发一下这个功能很方便 | *** @@ -32,15 +32,16 @@ 4. **支持依赖注入,可单独作为依赖注入框架使用** 5. **支持InstantRun** 6. **支持MultiDex**(Google方案) -7. 支持用户指定全局降级与局部降级策略 -8. 页面、拦截器、服务等组件均自动注册到框架 -9. 支持多种方式配置转场动画 -10. 支持获取Fragment -11. 完全支持Kotlin以及混编 +7. 映射关系按组分类、多级管理,按需初始化 +8. 支持用户指定全局降级与局部降级策略 +9. 页面、拦截器、服务等组件均自动注册到框架 +10. 支持多种方式配置转场动画 +11. 支持获取Fragment 12. **支持第三方 App 加固** 13. **支持生成路由文档** 14. 支持增量编译 -15. 支持动态注册路由信息和拦截器 +15. 支持动态注册路由、路由组、服务和拦截器 +16. 支持多模块Application生命周期(待开发) ## 二、典型应用 @@ -48,6 +49,7 @@ 2. 跨模块页面跳转,模块间解耦 3. 拦截跳转过程,处理登陆、埋点等逻辑 4. 跨模块API调用,通过控制反转来做组件解耦 +5. 多模块Application生命周期(待开发) ## 三、基础功能 @@ -72,7 +74,7 @@ dependencies { } ``` -##### 2. 在module项目下添加注解生成类依赖和配置 (如只使用java方式注册,可忽略此步骤) +##### 2. 在module项目下添加注解处理器依赖和配置 (如只使用java方式注册,可忽略此步骤) ```groovy android { @@ -98,10 +100,11 @@ dependencies { module_user模块Demo示例[module_user/build.gradle](https://github.com/wyjsonGo/GoRouter/blob/master/module_user/build.gradle) -##### 3. 添加Activity/Fragment +##### 3. 添加路由 ```java -// 注解 +// 在支持路由的页面上添加注解 +// 这里的路径需要注意的是至少需要有两级,/xx/xx @Route(path = "/test/activity") public class TestActivity extend Activity { ... @@ -112,10 +115,9 @@ public class TestActivity extend Activity { ```java if (BuildConfig.DEBUG) { - GoRouter.openDebug(); // 开启调试,查看路由详细注册和跳转过程日志 - // GoRouter.printStackTrace(); // 打印日志的时候打印线程堆栈 + GoRouter.openDebug(); // 开启调试,查看路由详细加载和跳转过程日志 } -GoRouter.autoLoadModuleRoute(this);// 尽可能早,推荐在Application中初始化 +GoRouter.autoLoadModuleRoute(this); // 尽可能早,推荐在Application中初始化 ``` ##### 5. 发起路由操作 @@ -131,7 +133,7 @@ GoRouter.getInstance().build("/test/fragment") .go(this); ``` -##### 6. 使用Gradle插件实现路由表的自动加载,支持Gradle8.0+ (可选) +##### 6. 使用Gradle插件实现路由表的自动加载,支持Gradle7.4+ (可选) ```groovy // 项目根目录下的settings.gradle @@ -162,7 +164,7 @@ plugins { id 'com.wyjson.gorouter' } ``` -* 支持Gradle8.0+,Gradle8.0以下参见5-7。 +* 支持Gradle7.4+,Gradle7.4以下参见5-7。 * 开发阶段构建加速参见5-8(最好在开发阶段开启,节省build时间)。 * 可选使用,通过GoRouter提供的注册插件进行路由表的自动加载,默认通过扫描dex的方式进行加载(在运行时注册,节省打包时间),通过gradle插件进行自动注册可以缩短运行时初始化时间(在打包时注册,节省运行时间),解决应用加固导致无法直接访问dex文件。 @@ -413,7 +415,7 @@ GoRouter.getInstance() // 指定Flag GoRouter.getInstance() .build("/main/activity") - .withFlags(); + .withFlags() .go(this); // 获取Fragment @@ -454,6 +456,9 @@ GoRouter.setLogger(); // 使用自己提供的线程池 GoRouter.setExecutor(); + +// 开启openDebug()后,打印日志的时候打印线程堆栈 +GoRouter.printStackTrace(); ``` ##### 3. 获取原始的URI @@ -478,19 +483,34 @@ GoRouter.getInstance().isRouteRegisterMode(); ##### 6. java方式动态注册路由信息 -适用于插件化架构的App以及需要动态注册路由信息和拦截器的场景,可以通过 GoRouter 提供的接口实现动态注册路由信息和拦截器。 +适用于插件化架构的App以及需要动态注册路由、路由组、服务和拦截器的场景。目标页面、服务和拦截器可以不标注`@Route`、`@Service`、`@Interceptor`注解。 ```java -// 注册Activity -GoRouter.getInstance().build("/user/info/activity").commitActivity(UserInfoActivity.class); -// 注册Fragment -GoRouter.getInstance().build("/user/card/fragment").commitFragment(CardFragment.class); -// 注册服务 +// 动态注册服务(重复添加相同服务会被覆盖(更新)) GoRouter.getInstance().addService(UserServiceImpl.class); -// 注册拦截器 + +// 注册拦截器(重复添加相同优先级会catch) GoRouter.getInstance().addInterceptor(1, TestInterceptor.class); -// 注册拦截器(适用于动态插件加载时使用) + +// 动态注册拦截器(重复添加相同优先级会覆盖(更新)) GoRouter.getInstance().setInterceptor(1, TestInterceptor.class); + +// 动态注册路由分组,按需加载路由(注意:同一批次仅允许相同group的路由信息注册) +GoRouter.getInstance().addRouterGroup("show", new IRouteModuleGroup() { + @Override + public void load() { + GoRouter.getInstance().build("/show/list/activity").commitActivity(ShowListActivity.class); + GoRouter.getInstance().build("/show/info/fragment").commitFragment(ShowInfoFragment.class); + ... + } +}); + +// 当然,你也可以直接注册Activity、Fragment路由 +// 动态注册Activity +GoRouter.getInstance().build("/user/info/activity").commitActivity(UserInfoActivity.class); +// 动态注册Fragment +GoRouter.getInstance().build("/user/card/fragment").commitFragment(CardFragment.class); + ``` ##### 7. 自定义模块路由加载 @@ -540,19 +560,31 @@ android { ## 六、其他 -##### 1. 拦截器和服务的异同 +##### 1. 路由中的分组概念 + +* SDK中针对所有的路径`/test/1`、`/test/2`进行分组,分组只有在分组中的某一个路径第一次被访问的时候,该分组才会被初始化。分组使用路径中第一段字符串(/*/)作为分组,这里的路径需要注意的是至少需要有两级`/xx/xx`。 +* GRouter允许一个module中存在多个分组,也允许多个module中存在相同的分组,但是最好不要在多个module中存在相同的分组,因为在注册路由组时发现存在相同的分组,会立即注册老的路由组里的全部路由,然后更新新的路由组信息。 + +##### 2. 拦截器和服务的异同 * 拦截器和服务所需要实现的接口不同,但是结构类似,都存在`init()`方法,但是两者的调用时机不同。 * 拦截器因为其特殊性,只对Activity路由有效,拦截器会在GoRouter首次调用的时候初始化。 * 服务没有该限制,某一服务可能在App整个生命周期中都不会用到,所以服务只有被调用的时候才会触发初始化操作。 -##### 2. 使用java方式注册服务,实现相同服务(HelloService)的实现类(HelloServiceImpl)调用`addService()`方法会被覆盖(更新),全局唯一。 +##### 3. 使用java方式注册服务 + +* 实现相同服务(HelloService)的实现类(HelloServiceImpl)调用`addService()`方法会被覆盖(更新),全局唯一。 + +##### 4. 使用java方式注册拦截器 + +* `addInterceptor(priority,interceptor)`重复添加相同优先级会catch。 +* `setInterceptor(priority,interceptor)`重复添加相同优先级会覆盖(更新)。 -##### 3. 使用java方式注册拦截器,`addInterceptor(priority,interceptor)`相同优先级添加会catch,`setInterceptor(priority,interceptor)`相同优先级添加会覆盖(更新)。 +##### 5. 混淆 -##### 4. 框架已经对注解方式注入参数做了混淆处理。如果不使用注解方式,使用java方式注册,不要忘记参数加上`@Keep`注解,否则使用`inject`方法自动注入会失败。 +* 框架已经做了混淆处理,开发者无需关心。需要注意的是,如果不使用`@Param`注解方式,使用java方式注册,不要忘记参数加上java自带`@Keep`注解,否则使用`inject()`方法自动注入会失败。 -##### 5. 开启调试,查看日志可以检查路由是否有重复提交的情况 +##### 6. 开启调试,查看日志可以检查路由是否有重复提交的情况 ```log [addCardMeta] Path duplicate commit!!! path[/xx/xx] @@ -563,7 +595,7 @@ android { ``` GoRouter日志tag为`GoRouter`,GoRouter-Compiler日志tag为`GoRouter::Compiler`,GoRouter-Gradle-Plugin日志tag为`GoRouter::Gradle-Plugin`。 -##### 6. ARouter迁移指南 +##### 7. ARouter迁移指南 | ARouter | GoRouter | | ------------------- | -------------------- | From 851035fe2b908030af47ee9bc0c6130c88698aa1 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sat, 11 Nov 2023 09:30:51 +0800 Subject: [PATCH 14/28] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=96=87=E6=A1=A3=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../router/compiler/doc/DocumentUtils.java | 14 ++++++- .../compiler/doc/model/DocumentModel.java | 22 ++++++++--- .../compiler/doc/model/InterceptorModel.java | 30 +++++++++++++-- .../router/compiler/doc/model/ParamModel.java | 16 ++++++++ .../router/compiler/doc/model/RouteModel.java | 38 ++++++++++++++----- .../compiler/doc/model/ServiceModel.java | 29 ++++++++++++-- .../GenerateModuleRouteProcessor.java | 12 ++++-- 7 files changed, 135 insertions(+), 26 deletions(-) diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java index e20a905..0ffa5da 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java @@ -84,7 +84,17 @@ public static void addInterceptorDoc(String moduleName, Logger logger, Element e } } - public static void addRouteDoc(String moduleName, Logger logger, Element element, Route route, String typeDoc) { + public static void addRouteGroupDoc(String moduleName, Logger logger, String group, List routeModelList) { + if (!isDocEnable) + return; + try { + documentModel.getRoutes().put(group, routeModelList); + } catch (Exception e) { + logger.error(moduleName + " Failed to add route group [" + group + "] document, " + e.getMessage()); + } + } + + public static void addRouteDoc(String moduleName, Logger logger, Element element, List routeModelList, Route route, String typeDoc) { if (!isDocEnable) return; try { @@ -97,7 +107,7 @@ public static void addRouteDoc(String moduleName, Logger logger, Element element routeModel.setTag(route.tag()); } addParamCode(moduleName, logger, element, routeModel); - documentModel.getRoutes().add(routeModel); + routeModelList.add(routeModel); } catch (Exception e) { logger.error(moduleName + " Failed to add route [" + element.toString() + "] document, " + e.getMessage()); } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/DocumentModel.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/DocumentModel.java index 6319488..bc274cf 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/DocumentModel.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/DocumentModel.java @@ -7,9 +7,9 @@ public class DocumentModel { - public Map services; - public List interceptors; - public List routes; + private Map services; + private List interceptors; + private Map> routes; public DocumentModel() { } @@ -21,6 +21,10 @@ public Map getServices() { return services; } + public void setServices(Map services) { + this.services = services; + } + public List getInterceptors() { if (interceptors == null) { interceptors = new ArrayList<>(); @@ -28,11 +32,19 @@ public List getInterceptors() { return interceptors; } - public List getRoutes() { + public void setInterceptors(List interceptors) { + this.interceptors = interceptors; + } + + public Map> getRoutes() { if (routes == null) { - routes = new ArrayList<>(); + routes = new HashMap<>(); } return routes; } + public void setRoutes(Map> routes) { + this.routes = routes; + } + } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/InterceptorModel.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/InterceptorModel.java index aed28a7..5530d72 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/InterceptorModel.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/InterceptorModel.java @@ -2,9 +2,9 @@ public class InterceptorModel { - public int priority; - public String remark; - public String className; + private int priority; + private String remark; + private String className; public InterceptorModel() { } @@ -14,4 +14,28 @@ public InterceptorModel(int priority, String className, String remark) { this.className = className; this.remark = remark; } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/ParamModel.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/ParamModel.java index 2ecbbd4..5f6522e 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/ParamModel.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/ParamModel.java @@ -17,18 +17,34 @@ public ParamModel(String name, String type, boolean required, String remark) { this.remark = remark; } + public String getName() { + return name; + } + public void setName(String name) { this.name = name; } + public String getType() { + return type; + } + public void setType(String type) { this.type = type; } + public boolean isRequired() { + return required; + } + public void setRequired(boolean required) { this.required = required; } + public String getRemark() { + return remark; + } + public void setRemark(String remark) { this.remark = remark; } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/RouteModel.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/RouteModel.java index f325233..c3020e6 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/RouteModel.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/RouteModel.java @@ -24,34 +24,54 @@ public RouteModel(String path, String type, String pathClass, Integer tag, List< this.remark = remark; } - public List getParamsType() { - if (paramsType == null) { - paramsType = new ArrayList<>(); - } - return paramsType; + public String getPath() { + return path; } public void setPath(String path) { this.path = path; } + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getType() { + return type; + } + public void setType(String type) { this.type = type; } + public String getPathClass() { + return pathClass; + } + public void setPathClass(String pathClass) { this.pathClass = pathClass; } + public Integer getTag() { + return tag; + } + public void setTag(Integer tag) { this.tag = tag; } - public void setParamsType(List paramsType) { - this.paramsType = paramsType; + public List getParamsType() { + if (paramsType == null) { + paramsType = new ArrayList<>(); + } + return paramsType; } - public void setRemark(String remark) { - this.remark = remark; + public void setParamsType(List paramsType) { + this.paramsType = paramsType; } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/ServiceModel.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/ServiceModel.java index 464a6a7..dc7957f 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/ServiceModel.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/ServiceModel.java @@ -2,9 +2,9 @@ public class ServiceModel { - public String remark; - public String prototype; - public String className; + private String remark; + private String prototype; + private String className; public ServiceModel() { } @@ -15,4 +15,27 @@ public ServiceModel(String prototype, String className, String remark) { this.remark = remark; } + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getPrototype() { + return prototype; + } + + public void setPrototype(String prototype) { + this.prototype = prototype; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index ac53d9b..e8a54cc 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -52,14 +52,17 @@ import com.wyjson.router.annotation.Route; import com.wyjson.router.annotation.Service; import com.wyjson.router.compiler.doc.DocumentUtils; +import com.wyjson.router.compiler.doc.model.RouteModel; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import java.io.IOException; +import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -205,6 +208,7 @@ private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironmen saveRouteGroup(elements); for (Map.Entry> entry : routeGroupMap.entrySet()) { + List routeModelDocList = new ArrayList<>(); String groupName = entry.getKey(); // 首字母大写 String groupNameToUpperCase = groupName.substring(0, 1).toUpperCase() + groupName.substring(1); @@ -212,7 +216,7 @@ private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironmen MethodSpec.Builder loadRouteForXGroupMethod = MethodSpec.methodBuilder(methodName).addModifiers(PRIVATE); loadRouteForXGroupMethod.addJavadoc("\"" + groupName + "\" route group"); for (Element element : entry.getValue()) { - addRoute(element, loadRouteForXGroupMethod); + addRoute(element, loadRouteForXGroupMethod, routeModelDocList); } MethodSpec loadRouteForXGroupMethodBuild = loadRouteForXGroupMethod.build(); routeGroupMethods.add(loadRouteForXGroupMethodBuild); @@ -229,8 +233,8 @@ private LinkedHashSet addRouteGroup(RoundEnvironment roundEnvironmen CodeBlock.Builder routeGroupPutCode = CodeBlock.builder(); routeGroupPutCode.add("$N.put($S, $N)", routeGroupsParamSpec, groupName, iRouteModuleGroupCode.build().toString()); - loadRouteGroupMethod.addStatement(routeGroupPutCode.build()); + DocumentUtils.addRouteGroupDoc(moduleName, logger, groupName, routeModelDocList); } loadIntoMethod.addCode("// call load route group\n"); @@ -278,7 +282,7 @@ private String extractRouteGroup(String path) { } } - private void addRoute(Element element, MethodSpec.Builder loadRouteGroupMethod) { + private void addRoute(Element element, MethodSpec.Builder loadRouteGroupMethod, List routeModelDocList) { Route route = element.getAnnotation(Route.class); TypeMirror tm = element.asType(); @@ -319,7 +323,7 @@ private void addRoute(Element element, MethodSpec.Builder loadRouteGroupMethod) unifyCode.add(typeCode.build()); loadRouteGroupMethod.addStatement(unifyCode.build()); - DocumentUtils.addRouteDoc(moduleName, logger, element, route, typeDoc); + DocumentUtils.addRouteDoc(moduleName, logger, element, routeModelDocList, route, typeDoc); } private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element element) { From 192a709ee89457f4cf2c043530af1e94da481834 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sat, 11 Nov 2023 12:01:54 +0800 Subject: [PATCH 15/28] update logo name --- app/src/main/AndroidManifest.xml | 2 +- .../src/main/res/drawable/main_splash_bg.xml | 2 +- .../{logo.png => main_ic_app_logo.png} | Bin 3 files changed, 2 insertions(+), 2 deletions(-) rename module_main/src/main/res/mipmap-xxhdpi/{logo.png => main_ic_app_logo.png} (100%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ed7ee58..db74a30 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ \ No newline at end of file diff --git a/module_main/src/main/res/mipmap-xxhdpi/logo.png b/module_main/src/main/res/mipmap-xxhdpi/main_ic_app_logo.png similarity index 100% rename from module_main/src/main/res/mipmap-xxhdpi/logo.png rename to module_main/src/main/res/mipmap-xxhdpi/main_ic_app_logo.png From ea2bd9c8bad83b8e034548d457158276cac8e6f9 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sat, 11 Nov 2023 12:22:56 +0800 Subject: [PATCH 16/28] =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=99=A8=E6=B7=BB=E5=8A=A0=E5=A2=9E=E9=87=8F=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/META-INF/gradle/incremental.annotation.processors | 1 + 1 file changed, 1 insertion(+) create mode 100644 GoRouter-Compiler/src/main/resources/META-INF/gradle/incremental.annotation.processors diff --git a/GoRouter-Compiler/src/main/resources/META-INF/gradle/incremental.annotation.processors b/GoRouter-Compiler/src/main/resources/META-INF/gradle/incremental.annotation.processors new file mode 100644 index 0000000..4b97163 --- /dev/null +++ b/GoRouter-Compiler/src/main/resources/META-INF/gradle/incremental.annotation.processors @@ -0,0 +1 @@ +com.wyjson.router.compiler.processor.GenerateModuleRouteProcessor,aggregating \ No newline at end of file From 6609824302c635333b99a2554d5f096e8d9ca859 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sat, 11 Nov 2023 12:34:40 +0800 Subject: [PATCH 17/28] delete org.gradle.unsafe.configuration-cache=true --- gradle.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6d76f67..a845fcd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,8 +20,6 @@ android.useAndroidX=true # thereby reducing the size of the R class for that library android.nonTransitiveRClass=true -org.gradle.unsafe.configuration-cache=true - # Debug APT # org.gradle.daemon=true # org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 From 703bd61fe6efd87b4c8d10ee41ef417c60eca77f Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sat, 11 Nov 2023 22:29:32 +0800 Subject: [PATCH 18/28] =?UTF-8?q?1.=E5=85=A8=E6=96=B0=E7=9A=84=E7=94=9F?= =?UTF-8?q?=E6=88=90=E8=B7=AF=E7=94=B1=E6=96=87=E6=A1=A3=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=202.=E5=BC=BA=E5=8C=96=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../router/core/InterceptorServiceImpl.java | 8 +- .../wyjson/router/core/LogisticsCenter.java | 17 +-- .../router/core/RouteModuleLoadCenter.java | 4 + .../com/wyjson/router/core/Warehouse.java | 8 +- .../router/exception/RouterException.java | 10 +- .../router/interfaces/IInterceptor.java | 2 +- .../com/wyjson/router/model/CardMeta.java | 7 +- .../com/wyjson/router/utils/RouteHashMap.java | 37 ++++++ .../wyjson/router/utils/ServiceHashMap.java | 23 ++++ .../router/compiler/doc/DocumentUtils.java | 7 +- .../compiler/processor/BaseProcessor.java | 6 +- .../router/compiler/utils/Constants.java | 3 +- GoRouter-Gradle-Plugin/build.gradle | 1 + .../gradle_plugin/doc/GenerateRouteDocTask.kt | 96 +++++++++++++++ .../gradle_plugin/doc/model/DocumentModel.kt | 7 ++ .../doc/model/InterceptorModel.kt | 7 ++ .../gradle_plugin/doc/model/ParamModel.kt | 8 ++ .../gradle_plugin/doc/model/RouteModel.kt | 10 ++ .../gradle_plugin/doc/model/ServiceModel.kt | 7 ++ .../launch/GradlePluginLaunch.kt | 30 +++-- .../router/gradle_plugin/utils/Constants.kt | 4 + README.md | 8 +- app/GoRouter-route-doc.json | 113 ++++++++++++++++++ module_common/build.gradle | 2 +- module_main/build.gradle | 2 +- module_user/build.gradle | 2 +- 26 files changed, 370 insertions(+), 59 deletions(-) create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/utils/RouteHashMap.java create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/utils/ServiceHashMap.java create mode 100644 GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt create mode 100644 GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/DocumentModel.kt create mode 100644 GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/InterceptorModel.kt create mode 100644 GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/ParamModel.kt create mode 100644 GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/RouteModel.kt create mode 100644 GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/ServiceModel.kt create mode 100644 app/GoRouter-route-doc.json diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/InterceptorServiceImpl.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/InterceptorServiceImpl.java index 8ed762e..989ae99 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/InterceptorServiceImpl.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/InterceptorServiceImpl.java @@ -1,13 +1,11 @@ package com.wyjson.router.core; -import androidx.annotation.NonNull; - import com.wyjson.router.GoRouter; import com.wyjson.router.callback.InterceptorCallback; -import com.wyjson.router.model.Card; import com.wyjson.router.core.interfaces.IInterceptorService; import com.wyjson.router.exception.RouterException; import com.wyjson.router.interfaces.IInterceptor; +import com.wyjson.router.model.Card; import com.wyjson.router.thread.CancelableCountDownLatch; import com.wyjson.router.utils.MapUtils; @@ -59,8 +57,8 @@ public void onContinue(Card card) { } @Override - public void onInterrupt(Card card, @NonNull Throwable exception) { - card.setInterceptorException(exception == null ? new RouterException() : exception); + public void onInterrupt(Card card, Throwable exception) { + card.setInterceptorException(exception == null ? new RouterException("The jump is blocked!") : exception); GoRouter.logger.warning(null, "[doInterceptions] [onInterrupt] {" + interceptorEntry.getKey() + "->" + interceptorEntry.getValue().getClass().getSimpleName() + "} message:" + card.getInterceptorException().getMessage()); counter.cancel(); } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java index 71e6d5c..82eb321 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java @@ -89,21 +89,6 @@ public static CardMeta getCardMeta(Card card) throws NoFoundRouteException { * @param cardMeta */ public static void addCardMeta(CardMeta cardMeta) { - if (TextUtils.isEmpty(cardMeta.getPath())) { - throw new RouterException("path Parameter is invalid!"); - } - // 检查路由是否有重复提交的情况 - if (GoRouter.isDebug()) { - for (Map.Entry cardMetaEntry : Warehouse.routes.entrySet()) { - if (TextUtils.equals(cardMetaEntry.getKey(), cardMeta.getPath())) { - GoRouter.logger.error(null, "[addCardMeta] Path duplicate commit!!! path[" + cardMetaEntry.getValue().getPath() + "]"); - break; - } else if (cardMetaEntry.getValue().getPathClass() == cardMeta.getPathClass()) { - GoRouter.logger.error(null, "[addCardMeta] PathClass duplicate commit!!! pathClass[" + cardMetaEntry.getValue().getPathClass() + "]"); - break; - } - } - } Warehouse.routes.put(cardMeta.getPath(), cardMeta); GoRouter.logger.debug(null, "[addCardMeta] size:" + Warehouse.routes.size() + ", commit:" + cardMeta); } @@ -170,7 +155,7 @@ public static void addInterceptor(int priority, Class in String title = isForce ? "[setInterceptor]" : "[addInterceptor]"; GoRouter.logger.debug(null, title + " size:" + Warehouse.interceptors.size() + ", priority:" + priority + " -> " + interceptor.getSimpleName()); } catch (Exception e) { - throw new RouterException(e); + throw new RouterException("[addInterceptor] " + e.getMessage()); } } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java index 09e0d32..fa5a663 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java @@ -86,6 +86,8 @@ private static void register(String className, boolean isPlugin) { "register failed, class name: " + className + " should implements one of IRouteModule."); } + } catch (RouterException e) { + throw new RouterException("[register] " + e.getMessage()); } catch (Exception e) { GoRouter.logger.error(null, "register class error:" + className, e); } @@ -134,6 +136,8 @@ private static void loadModuleRouteByDex(Application context) { } GoRouter.logger.info(null, "The loading module route is complete, cost " + (System.currentTimeMillis() - startTime) + "ms."); + } catch (RouterException e) { + throw new RouterException("[loadModuleRouteByDex] " + e.getMessage()); } catch (Exception e) { throw new RouterException("GoRouter [loadModuleRouteByDex] exception! [" + e.getMessage() + "]"); } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java index aa46a1e..de63e00 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java @@ -7,16 +7,18 @@ import com.wyjson.router.module.interfaces.IRouteModuleGroup; import com.wyjson.router.utils.InterceptorTreeMap; import com.wyjson.router.utils.RouteGroupHashMap; +import com.wyjson.router.utils.RouteHashMap; +import com.wyjson.router.utils.ServiceHashMap; -import java.util.HashMap; import java.util.Map; class Warehouse { static final Map routeGroups = new RouteGroupHashMap(); - static final Map routes = new HashMap<>(); - static final Map, ServiceMeta> services = new HashMap<>(); + static final Map routes = new RouteHashMap(); + + static final Map, ServiceMeta> services = new ServiceHashMap(); static final Map interceptors = new InterceptorTreeMap<>("More than one interceptors use same priority [%s]"); diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/exception/RouterException.java b/GoRouter-Api/src/main/java/com/wyjson/router/exception/RouterException.java index 1a47380..5a28c3e 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/exception/RouterException.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/exception/RouterException.java @@ -2,18 +2,16 @@ import android.os.Build; +import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; public class RouterException extends RuntimeException { - public RouterException() { - } - - public RouterException(String message) { + public RouterException(@NonNull String message) { super(message); } - public RouterException(String message, Throwable cause) { + public RouterException(@NonNull String message, Throwable cause) { super(message, cause); } @@ -22,7 +20,7 @@ public RouterException(Throwable cause) { } @RequiresApi(api = Build.VERSION_CODES.N) - public RouterException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + public RouterException(@NonNull String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IInterceptor.java b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IInterceptor.java index 68bb05e..d20e46c 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IInterceptor.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IInterceptor.java @@ -11,7 +11,7 @@ public interface IInterceptor { void init(); /** - * {@link InterceptorCallback#onContinue(Card)} 继续执行 + * {@link InterceptorCallback#onContinue(Card)} 继续执行, * {@link InterceptorCallback#onInterrupt(Card, Throwable)}} 拦截 * * @param card diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/model/CardMeta.java b/GoRouter-Api/src/main/java/com/wyjson/router/model/CardMeta.java index 62dba04..7cbb669 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/model/CardMeta.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/model/CardMeta.java @@ -98,15 +98,18 @@ public Map getParamsType() { return paramsType; } - public void commitActivity(Class cls) { + public void commitActivity(@NonNull Class cls) { commit(cls, RouteType.ACTIVITY); } - public void commitFragment(Class cls) { + public void commitFragment(@NonNull Class cls) { commit(cls, RouteType.FRAGMENT); } private void commit(Class cls, RouteType type) { + if (cls == null) { + throw new RouterException("Cannot commit empty!"); + } LogisticsCenter.addCardMeta(new CardMeta(this.path, type, cls, this.tag, this.paramsType)); } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/utils/RouteHashMap.java b/GoRouter-Api/src/main/java/com/wyjson/router/utils/RouteHashMap.java new file mode 100644 index 0000000..e336b79 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/utils/RouteHashMap.java @@ -0,0 +1,37 @@ +package com.wyjson.router.utils; + +import androidx.annotation.Nullable; + +import com.wyjson.router.GoRouter; +import com.wyjson.router.model.CardMeta; + +import java.util.HashMap; +import java.util.Map; + +public class RouteHashMap extends HashMap { + + @Nullable + @Override + public CardMeta put(String key, CardMeta value) { + // 检查路由是否有重复提交的情况(仅对使用java注册方式有效) + if (GoRouter.isDebug()) { + if (containsKey(key)) { + GoRouter.logger.error(null, "route path[" + key + "] duplicate commit!!!"); + } else if (containsValue(value)) { + GoRouter.logger.error(null, "route pathClass[" + value.getPathClass() + "] duplicate commit!!!"); + } + } + return super.put(key, value); + } + + public boolean containsValue(CardMeta value) { + if (size() == 0) + return false; + for (Map.Entry entry : entrySet()) { + if (entry.getValue().getPathClass() == value.getPathClass()) { + return true; + } + } + return false; + } +} diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/utils/ServiceHashMap.java b/GoRouter-Api/src/main/java/com/wyjson/router/utils/ServiceHashMap.java new file mode 100644 index 0000000..7455440 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/utils/ServiceHashMap.java @@ -0,0 +1,23 @@ +package com.wyjson.router.utils; + +import androidx.annotation.Nullable; + +import com.wyjson.router.GoRouter; +import com.wyjson.router.interfaces.IService; +import com.wyjson.router.model.ServiceMeta; + +import java.util.HashMap; + +public class ServiceHashMap extends HashMap, ServiceMeta> { + + @Nullable + @Override + public ServiceMeta put(Class key, ServiceMeta value) { + // [xx]服务已经在[xxx]实现中注册,并将被覆盖(更新)。 + if (containsKey(key)) { + GoRouter.logger.warning(null, "The [" + key.getSimpleName() + "] service has been registered in the [" + value.getServiceClass().getSimpleName() + "] implementation and will be overridden (updated)."); + } + return super.put(key, value); + } + +} diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java index 0ffa5da..8343296 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java @@ -1,8 +1,9 @@ package com.wyjson.router.compiler.doc; import static com.wyjson.router.compiler.utils.Constants.DOCS_PACKAGE_NAME; +import static com.wyjson.router.compiler.utils.Constants.DOCUMENT_FILE_NAME; -import com.google.gson.GsonBuilder; +import com.google.gson.Gson; import com.wyjson.router.annotation.Interceptor; import com.wyjson.router.annotation.Param; import com.wyjson.router.annotation.Route; @@ -43,7 +44,7 @@ public static void createDoc(Filer mFiler, String moduleName, Logger logger, boo docWriter = mFiler.createResource( StandardLocation.SOURCE_OUTPUT, DOCS_PACKAGE_NAME, - moduleName + "-gorouter-doc.json" + moduleName + "-" + DOCUMENT_FILE_NAME ).openWriter(); } catch (IOException e) { logger.error(moduleName + " Failed to create the document because " + e.getMessage()); @@ -54,7 +55,7 @@ public static void generateDoc(String moduleName, Logger logger) { if (!isDocEnable) return; try { - docWriter.append(new GsonBuilder().setPrettyPrinting().create().toJson(documentModel)); + docWriter.append(new Gson().toJson(documentModel)); docWriter.flush(); docWriter.close(); } catch (IOException e) { diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/BaseProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/BaseProcessor.java index 1d0a6d9..5fd9c87 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/BaseProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/BaseProcessor.java @@ -1,10 +1,8 @@ package com.wyjson.router.compiler.processor; -import static com.wyjson.router.compiler.utils.Constants.KEY_GENERATE_DOC_NAME; import static com.wyjson.router.compiler.utils.Constants.KEY_MODULE_NAME; import static com.wyjson.router.compiler.utils.Constants.NO_MODULE_NAME_TIPS; import static com.wyjson.router.compiler.utils.Constants.PREFIX_OF_LOGGER; -import static com.wyjson.router.compiler.utils.Constants.VALUE_ENABLE; import com.wyjson.router.compiler.utils.Logger; @@ -31,7 +29,7 @@ public abstract class BaseProcessor extends AbstractProcessor { // Module name, maybe its 'app' or others String moduleName = null; String generateClassName; - boolean isGenerateDoc; + boolean isGenerateDoc = true; @Override public synchronized void init(ProcessingEnvironment processingEnv) { @@ -46,7 +44,6 @@ public synchronized void init(ProcessingEnvironment processingEnv) { Map options = processingEnv.getOptions(); if (MapUtils.isNotEmpty(options)) { moduleName = options.get(KEY_MODULE_NAME); - isGenerateDoc = VALUE_ENABLE.equals(options.get(KEY_GENERATE_DOC_NAME)); } if (StringUtils.isNotEmpty(moduleName)) { @@ -92,7 +89,6 @@ public SourceVersion getSupportedSourceVersion() { public Set getSupportedOptions() { return new HashSet() {{ this.add(KEY_MODULE_NAME); - this.add(KEY_GENERATE_DOC_NAME); }}; } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java index aa32281..c47c98b 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java @@ -5,6 +5,7 @@ public class Constants { public static final String PROJECT = "GoRouter"; public static final String SEPARATOR = "$$"; public static final String WARNING_TIPS = "DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY GOROUTER."; + public static final String DOCUMENT_FILE_NAME = "route-doc.json"; // System interface public static final String ACTIVITY = "android.app.Activity"; @@ -45,8 +46,6 @@ public class Constants { // Options of processor public static final String KEY_MODULE_NAME = "GOROUTER_MODULE_NAME"; - public static final String KEY_GENERATE_DOC_NAME = "GOROUTER_GENERATE_DOC"; - public static final String VALUE_ENABLE = "enable"; // Java type private static final String LANG = "java.lang"; diff --git a/GoRouter-Gradle-Plugin/build.gradle b/GoRouter-Gradle-Plugin/build.gradle index 0a40b2f..7c8960b 100644 --- a/GoRouter-Gradle-Plugin/build.gradle +++ b/GoRouter-Gradle-Plugin/build.gradle @@ -14,6 +14,7 @@ dependencies { implementation 'com.android.tools.build:gradle:8.1.2' implementation 'org.ow2.asm:asm:9.2' implementation 'org.ow2.asm:asm-commons:9.2' + implementation 'com.google.code.gson:gson:2.10.1' } apply from: rootProject.file('gradle/publish-java.gradle') \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt new file mode 100644 index 0000000..47d5907 --- /dev/null +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt @@ -0,0 +1,96 @@ +package com.wyjson.router.gradle_plugin.doc + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.wyjson.router.gradle_plugin.doc.model.DocumentModel +import com.wyjson.router.gradle_plugin.utils.Constants +import com.wyjson.router.gradle_plugin.utils.Constants.GENERATE_ROUTE_DOC_TASK_NAME +import com.wyjson.router.gradle_plugin.utils.Logger +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency +import org.gradle.api.tasks.TaskAction +import java.io.File + +abstract class GenerateRouteDocTask : DefaultTask() { + + init { + group = Constants.PROJECT + } + + private val documentName = "${project.rootProject.name}-${Constants.DOCUMENT_FILE_NAME}" + private val docOutFilePath = "${project.projectDir}/${documentName}" + private var document: DocumentModel? = null + + @TaskAction + fun taskAction() { + Logger.i("Generate GoRouter document task start.") + project.dependProject().forEach { curProject -> + val genFile = + curProject.file("${curProject.buildDir}/generated/ap_generated_sources/debug") + .listFiles() + val collection = + curProject.files(genFile).asFileTree.filter { it.name.endsWith(Constants.DOCUMENT_FILE_NAME) } + if (collection.isEmpty) { + Logger.w("project[${curProject.name}] scan 0 route document.") + } else { + for (file in collection) { + Logger.i("project[${curProject.name}] found the file[${file.name}].") + mergeRouteModuleDoc(curProject, file) + } + } + } + if (document == null) { + if (GENERATE_ROUTE_DOC_TASK_NAME == name) { + Logger.e("Failed to generate the route document!") + } else { + Logger.e("Failed to generate the route document! Use the '${GENERATE_ROUTE_DOC_TASK_NAME}' task to generate a new route document.") + } + return + } + val json = GsonBuilder().setPrettyPrinting().create().toJson(document) + File(docOutFilePath).writeText(json, Charsets.UTF_8) + Logger.i("Generate GoRouter document task end.") + Logger.i("Success! route document name[${documentName}] $docOutFilePath") + } + + private fun mergeRouteModuleDoc(curProject: Project, file: File) { + if (file.readLines().isNotEmpty()) { + try { + val documentModel = Gson().fromJson(file.readLines()[0], DocumentModel::class.java); + if (document == null) { + document = documentModel; + } else { + document!!.services.putAll(documentModel.services) + document!!.interceptors.addAll(documentModel.interceptors) + document!!.routes.putAll(documentModel.routes) + } + document!!.interceptors.sortBy { interceptor -> interceptor.priority } + } catch (e: Exception) { + Logger.e("module[${curProject.name}] route document parsing failed, do not modify the generated route file, use the '${GENERATE_ROUTE_DOC_TASK_NAME}' task to generate a new route document.") + } + } else { + Logger.e("module[${curProject.name}] route document content is empty and a new route document is generated using the '${GENERATE_ROUTE_DOC_TASK_NAME}' task.") + } + } + + /** + * 查询项目下的依赖项目,递归子项目 + */ + private fun Project.dependProject(): List { + val projects = ArrayList() + arrayOf("api", "implementation").forEach { name -> + val dependencyProjects = configurations.getByName(name).dependencies + .filterIsInstance() + .filter { it.dependencyProject.isAndroid() } + .map { it.dependencyProject } + projects.addAll(dependencyProjects) + dependencyProjects.forEach { projects.addAll(it.dependProject()) } + } + return projects.distinct() + } + + private fun Project.isAndroid() = + plugins.hasPlugin("com.android.application") || plugins.hasPlugin("com.android.library") + +} \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/DocumentModel.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/DocumentModel.kt new file mode 100644 index 0000000..083ec22 --- /dev/null +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/DocumentModel.kt @@ -0,0 +1,7 @@ +package com.wyjson.router.gradle_plugin.doc.model + +data class DocumentModel( + var services: HashMap = HashMap(), + var interceptors: ArrayList = ArrayList(), + var routes: HashMap> = HashMap() +) \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/InterceptorModel.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/InterceptorModel.kt new file mode 100644 index 0000000..0feac12 --- /dev/null +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/InterceptorModel.kt @@ -0,0 +1,7 @@ +package com.wyjson.router.gradle_plugin.doc.model + +data class InterceptorModel( + var priority: Int, + var remark: String?, + var className: String? +) \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/ParamModel.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/ParamModel.kt new file mode 100644 index 0000000..5bf8db5 --- /dev/null +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/ParamModel.kt @@ -0,0 +1,8 @@ +package com.wyjson.router.gradle_plugin.doc.model + +data class ParamModel( + var name: String?, + var type: String?, + var isRequired: Boolean, + var remark: String? +) \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/RouteModel.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/RouteModel.kt new file mode 100644 index 0000000..b990903 --- /dev/null +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/RouteModel.kt @@ -0,0 +1,10 @@ +package com.wyjson.router.gradle_plugin.doc.model + +data class RouteModel( + var path: String?, + var remark: String?, + var type: String?, + var pathClass: String?, + var tag: Int?, + var paramsType: List? +) \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/ServiceModel.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/ServiceModel.kt new file mode 100644 index 0000000..0da3089 --- /dev/null +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/ServiceModel.kt @@ -0,0 +1,7 @@ +package com.wyjson.router.gradle_plugin.doc.model + +data class ServiceModel( + var remark: String?, + var prototype: String?, + var className: String? +) \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/launch/GradlePluginLaunch.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/launch/GradlePluginLaunch.kt index c88ffe2..18ce986 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/launch/GradlePluginLaunch.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/launch/GradlePluginLaunch.kt @@ -4,8 +4,13 @@ import com.android.build.api.artifact.ScopedArtifact import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.ScopedArtifacts import com.android.build.gradle.AppPlugin +import com.android.build.gradle.internal.tasks.factory.dependsOn import com.wyjson.router.gradle_plugin.config.GoRouterConfig import com.wyjson.router.gradle_plugin.core.AssembleModuleRouteTask +import com.wyjson.router.gradle_plugin.doc.GenerateRouteDocTask +import com.wyjson.router.gradle_plugin.utils.Constants.ASSEMBLE_MODULE_ROUTE_TASK_TASK_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.GENERATE_ROUTE_DOC_TASK_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.QUICK_GENERATE_ROUTE_DOC_TASK_NAME import com.wyjson.router.gradle_plugin.utils.Logger import org.gradle.api.Plugin import org.gradle.api.Project @@ -18,6 +23,10 @@ class GradlePluginLaunch : Plugin { Logger.e("Plugin ['com.wyjson.Gorouter'] can only be used under the application, not under the module library invalid!") return } + project.tasks.register(GENERATE_ROUTE_DOC_TASK_NAME, GenerateRouteDocTask::class.java) + .dependsOn("build") + project.tasks.register(QUICK_GENERATE_ROUTE_DOC_TASK_NAME, GenerateRouteDocTask::class.java) + project.extensions.add("GoRouter", GoRouterConfig::class.java) val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java) androidComponents.onVariants { variant -> @@ -35,16 +44,19 @@ class GradlePluginLaunch : Plugin { isRunTask = true } if (isRunTask) { - val task = project.tasks.register("${variant.name}AssembleModuleRouteTask", AssembleModuleRouteTask::class.java) + val task = project.tasks.register( + "${variant.name}${ASSEMBLE_MODULE_ROUTE_TASK_TASK_NAME}", + AssembleModuleRouteTask::class.java + ) variant.artifacts - .forScope(ScopedArtifacts.Scope.ALL) - .use(task) - .toTransform( - ScopedArtifact.CLASSES, - AssembleModuleRouteTask::allJars, - AssembleModuleRouteTask::allDirectories, - AssembleModuleRouteTask::output - ) + .forScope(ScopedArtifacts.Scope.ALL) + .use(task) + .toTransform( + ScopedArtifact.CLASSES, + AssembleModuleRouteTask::allJars, + AssembleModuleRouteTask::allDirectories, + AssembleModuleRouteTask::output + ) } } } diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt index 09642ba..b5b2302 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt @@ -1,11 +1,15 @@ package com.wyjson.router.gradle_plugin.utils object Constants { + const val GENERATE_ROUTE_DOC_TASK_NAME = "generateRouteDoc"; + const val QUICK_GENERATE_ROUTE_DOC_TASK_NAME = "quickGenerateRouteDoc"; + const val ASSEMBLE_MODULE_ROUTE_TASK_TASK_NAME = "AssembleModuleRouteTask"; private const val SEPARATOR = "$$"; private const val PACKAGE_NAME = "com.wyjson.router" const val PROJECT = "GoRouter"; + const val DOCUMENT_FILE_NAME = "route-doc.json" const val _CLASS = ".class" // 路由注册生成类名后缀$$GoRouter diff --git a/README.md b/README.md index a140d48..c829cd7 100644 --- a/README.md +++ b/README.md @@ -545,7 +545,7 @@ GoRouter { ```java // 更新 build.gradle, 添加参数 GOROUTER_GENERATE_DOC = enable -// 生成的文档路径 : build/generated/ap_generated_sources/(debug or release)/out/com/wyjson/router/docs/${moduleName}-gorouter-doc.json +// 生成的文档路径 : build/generated/ap_generated_sources/(debug or release)/out/com/wyjson/router/docs/${moduleName}-route-doc.json android { defaultConfig { ... @@ -584,14 +584,14 @@ android { * 框架已经做了混淆处理,开发者无需关心。需要注意的是,如果不使用`@Param`注解方式,使用java方式注册,不要忘记参数加上java自带`@Keep`注解,否则使用`inject()`方法自动注入会失败。 -##### 6. 开启调试,查看日志可以检查路由是否有重复提交的情况 +##### 6. 开启调试,查看日志可以检查使用java方式注册的路由是否有重复提交的情况 ```log -[addCardMeta] Path duplicate commit!!! path[/xx/xx] +route path[/xx/xx] duplicate commit!!! ``` ```log -[addCardMeta] PathClass duplicate commit!!! pathClass[class xx.xx] +route pathClass[class xx.xx] duplicate commit!!! ``` GoRouter日志tag为`GoRouter`,GoRouter-Compiler日志tag为`GoRouter::Compiler`,GoRouter-Gradle-Plugin日志tag为`GoRouter::Gradle-Plugin`。 diff --git a/app/GoRouter-route-doc.json b/app/GoRouter-route-doc.json new file mode 100644 index 0000000..f6c3058 --- /dev/null +++ b/app/GoRouter-route-doc.json @@ -0,0 +1,113 @@ +{ + "services": { + "UserService": { + "remark": "用户服务", + "prototype": "com.wyjson.module_common.route.service.user.UserService", + "className": "com.wyjson.module_user.route.service.UserServiceImpl" + }, + "IDegradeService": { + "remark": "全局降级策略", + "prototype": "com.wyjson.router.interfaces.IDegradeService", + "className": "com.wyjson.module_common.route.service.DegradeServiceImpl" + }, + "IPretreatmentService": { + "remark": "预处理服务", + "prototype": "com.wyjson.router.interfaces.IPretreatmentService", + "className": "com.wyjson.module_common.route.service.PretreatmentServiceImpl" + } + }, + "interceptors": [ + { + "priority": 1, + "remark": "登录拦截器", + "className": "com.wyjson.module_user.route.interceptor.SignInInterceptor" + }, + { + "priority": 100, + "remark": "身份验证拦截器", + "className": "com.wyjson.module_user.route.interceptor.AuthenticationInterceptor" + } + ], + "routes": { + "new": [ + { + "path": "/new/param/activity", + "remark": "参数页面", + "type": "Activity", + "pathClass": "com.wyjson.module_user.activity.ParamActivity", + "paramsType": [ + { + "name": "base", + "type": "int", + "isRequired": false, + "remark": "我是一个父类字段" + }, + { + "name": "age", + "type": "int", + "isRequired": false + }, + { + "name": "nickname", + "type": "String", + "isRequired": false, + "remark": "昵称" + } + ] + }, + { + "path": "/new/param/fragment", + "remark": "参数片段", + "type": "Fragment", + "pathClass": "com.wyjson.module_user.fragment.ParamFragment", + "paramsType": [ + { + "name": "age", + "type": "int", + "isRequired": false + }, + { + "name": "name", + "type": "String", + "isRequired": false + } + ] + } + ], + "main": [ + { + "path": "/main/activity", + "remark": "主页", + "type": "Activity", + "pathClass": "com.wyjson.module_main.activity.MainActivity" + }, + { + "path": "/main/splash/activity", + "remark": "欢迎页", + "type": "Activity", + "pathClass": "com.wyjson.module_main.activity.SplashActivity" + } + ], + "user": [ + { + "path": "/user/card/fragment", + "remark": "卡片片段", + "type": "Fragment", + "pathClass": "com.wyjson.module_user.fragment.CardFragment" + }, + { + "path": "/user/info/activity", + "remark": "用户信息页面", + "type": "Activity", + "pathClass": "com.wyjson.module_user.activity.UserInfoActivity", + "tag": 3 + }, + { + "path": "/user/sign_in/activity", + "remark": "登录页面", + "type": "Activity", + "pathClass": "com.wyjson.module_user.activity.SignInActivity" + } + ] + } +} \ No newline at end of file diff --git a/module_common/build.gradle b/module_common/build.gradle index 67d1444..59a15cd 100644 --- a/module_common/build.gradle +++ b/module_common/build.gradle @@ -12,7 +12,7 @@ android { javaCompileOptions { annotationProcessorOptions { - arguments = [GOROUTER_MODULE_NAME: project.getName(), GOROUTER_GENERATE_DOC: "enable"] + arguments = [GOROUTER_MODULE_NAME: project.getName()] } } } diff --git a/module_main/build.gradle b/module_main/build.gradle index 91ef92f..f5fb38a 100644 --- a/module_main/build.gradle +++ b/module_main/build.gradle @@ -12,7 +12,7 @@ android { javaCompileOptions { annotationProcessorOptions { - arguments = [GOROUTER_MODULE_NAME: project.getName(), GOROUTER_GENERATE_DOC: "enable"] + arguments = [GOROUTER_MODULE_NAME: project.getName()] } } } diff --git a/module_user/build.gradle b/module_user/build.gradle index 0be4006..a84af7a 100644 --- a/module_user/build.gradle +++ b/module_user/build.gradle @@ -12,7 +12,7 @@ android { javaCompileOptions { annotationProcessorOptions { - arguments = [GOROUTER_MODULE_NAME: project.getName(), GOROUTER_GENERATE_DOC: "enable"] + arguments = [GOROUTER_MODULE_NAME: project.getName()] } } } From 287d7d32caaa2d8c1fe8c237af66effe1bcc2d64 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sun, 12 Nov 2023 10:35:40 +0800 Subject: [PATCH 19/28] update README.md --- README.md | 29 ++++++++++-------- .../gradle_task_generate_router_doc.png | Bin 0 -> 20008 bytes 2 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 screenshot/gradle_task_generate_router_doc.png diff --git a/README.md b/README.md index c829cd7..da04b19 100644 --- a/README.md +++ b/README.md @@ -543,20 +543,23 @@ GoRouter { ##### 9. 生成路由文档 -```java -// 更新 build.gradle, 添加参数 GOROUTER_GENERATE_DOC = enable -// 生成的文档路径 : build/generated/ap_generated_sources/(debug or release)/out/com/wyjson/router/docs/${moduleName}-route-doc.json -android { - defaultConfig { - ... - javaCompileOptions { - annotationProcessorOptions { - arguments = [GOROUTER_MODULE_NAME: project.getName(), GOROUTER_GENERATE_DOC: "enable"] - } - } - } -} +使用gradle命令一键生成路由文档 + +```sh +./gradlew generateRouteDoc +# 或使用快速生成 +./gradlew quickGenerateRouteDoc ``` +当然你也可以使用图形页面执行任务 + + + +两条任务的区别是: + +* 执行`generateRouteDoc`任务会先自动触发`build`任务生成各个模块子路由文档,在触发生成最终的路由文档。 +* 执行`quickGenerateRouteDoc`任务会直接去获取子模块路由文档生成最终的路由文档(如果你已经运行过项目,可以使用此任务快速得到结果)。 + +生成的路由文档会保存到项目下的`/app/项目名-route-doc.json`,Demo示例[/app/GoRouter-route-doc.json](https://github.com/wyjsonGo/GoRouter/blob/master/app/GoRouter-route-doc.json) ## 六、其他 diff --git a/screenshot/gradle_task_generate_router_doc.png b/screenshot/gradle_task_generate_router_doc.png new file mode 100644 index 0000000000000000000000000000000000000000..78fe2783b96a374e6c0c71f1cddf0c52384d9aba GIT binary patch literal 20008 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 H$HV^ulALd& literal 0 HcmV?d00001 From d4b5fc0debd6266302f21335332936d89402ad86 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sun, 12 Nov 2023 11:03:05 +0800 Subject: [PATCH 20/28] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=9A=84=E8=B7=AF=E7=94=B1=E5=8A=A0=E8=BD=BD=E7=B1=BB=E5=8C=85?= =?UTF-8?q?=E7=9A=84=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/wyjson/router/core/RouteModuleLoadCenter.java | 2 +- .../main/java/com/wyjson/router/compiler/utils/Constants.java | 2 +- .../kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt | 2 +- README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java index fa5a663..0fc674c 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java @@ -107,7 +107,7 @@ private static void markRegisteredByPlugin() { public static final String GOROUTER_SP_KEY_MAP = "ROUTE_MODULE_MAP"; public static final String SEPARATOR = "$$"; // 路由注册生成类所在包名 - public static final String ROUTE_MODULE_PACKAGE = "com.wyjson.router.module"; + public static final String ROUTE_MODULE_PACKAGE = "com.wyjson.router.module.route"; // 路由注册生成类名后缀$$GoRouter public static final String MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "GoRouter"; diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java index c47c98b..739ed14 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java @@ -15,7 +15,7 @@ public class Constants { public static final String DOCS_PACKAGE_NAME = PACKAGE_NAME + ".docs"; public static final String GOROUTER_PACKAGE_NAME = PACKAGE_NAME + ".GoRouter"; - public static final String MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module"; + public static final String MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module.route"; public static final String I_ROUTE_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module.interfaces.IRouteModule"; public static final String METHOD_NAME_LOAD = "load"; public static final String METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP = "loadRouteFor%sGroup"; diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt index b5b2302..24bc32a 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt @@ -16,7 +16,7 @@ object Constants { const val MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "GoRouter" // 需要扫描注入的类,所在的包名 - const val SCAN_TARGET_INJECT_PACKAGE_NAME = "$PACKAGE_NAME.module" + const val SCAN_TARGET_INJECT_PACKAGE_NAME = "$PACKAGE_NAME.module.route" // 注入到这个类下 const val INJECT_CLASS_NAME = "$PACKAGE_NAME.core.RouteModuleLoadCenter" diff --git a/README.md b/README.md index da04b19..c9b2243 100644 --- a/README.md +++ b/README.md @@ -516,7 +516,7 @@ GoRouter.getInstance().build("/user/card/fragment").commitFragment(CardFragment. ##### 7. 自定义模块路由加载 如不使用gradle插件[3-6]进行自动注册,也不想走默认扫描dex的方式,可以不调用`GoRouter.autoLoadModuleRoute(this);`方法,但需要自行调用模块生成的路由加载类。 -模块项目里至少使用一条注解`@Route`、`@Service`、`@Interceptor`,就会生成对应路由表的加载类。路由表加载类命名规则会根据`GOROUTER_MODULE_NAME `设置的模块名称转换成大写驼峰命名+`$$GoRouter.java`,所有模块生成的路由表加载类都会放到`com.wyjson.router.module`包下。 +模块项目里至少使用一条注解`@Route`、`@Service`、`@Interceptor`,就会生成对应路由表的加载类。路由表加载类命名规则会根据`GOROUTER_MODULE_NAME `设置的模块名称转换成大写驼峰命名+`$$GoRouter.java`,所有模块生成的路由表加载类都会放到`com.wyjson.router.module.route`包下。 例如模块名称`module_user`会生成`ModuleUser$$GoRouter.java` ```java From 7f9de450240dda9c31c921936b9b3ec808fee57b Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sun, 12 Nov 2023 11:46:02 +0800 Subject: [PATCH 21/28] =?UTF-8?q?=E4=BF=AE=E6=94=B9service=E7=9A=84priorit?= =?UTF-8?q?y=E5=88=B0ordinal,=E8=BF=98=E6=98=AF=E4=BB=8E=E5=B0=8F=E6=89=93?= =?UTF-8?q?=E5=88=B0=E6=89=A7=E8=A1=8C=E6=8B=A6=E6=88=AA=E5=99=A8,?= =?UTF-8?q?=E5=8F=AA=E6=98=AF=E8=A7=84=E8=8C=83=E4=BA=86=E4=B8=80=E4=B8=8B?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wyjson/router/annotation/Interceptor.java | 5 ++-- .../main/java/com/wyjson/router/GoRouter.java | 16 ++++++------- .../wyjson/router/core/LogisticsCenter.java | 23 ++++++++----------- .../com/wyjson/router/core/Warehouse.java | 2 +- .../router/compiler/doc/DocumentUtils.java | 2 +- .../compiler/doc/model/InterceptorModel.java | 14 +++++------ .../GenerateModuleRouteProcessor.java | 2 +- .../gradle_plugin/doc/GenerateRouteDocTask.kt | 2 +- .../doc/model/InterceptorModel.kt | 2 +- README.md | 12 +++++----- app/GoRouter-route-doc.json | 4 ++-- .../AuthenticationInterceptor.java | 2 +- .../route/interceptor/SignInInterceptor.java | 2 +- 13 files changed, 43 insertions(+), 45 deletions(-) diff --git a/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/Interceptor.java b/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/Interceptor.java index ac4410a..c9d11a4 100644 --- a/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/Interceptor.java +++ b/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/Interceptor.java @@ -10,9 +10,10 @@ @Retention(SOURCE) public @interface Interceptor { /** - * The priority of interceptor, GoRouter will be excute them follow the priority. + * The ordinal of interceptor, GoRouter will be execute them follow the ordinal. + * Execute from small to large */ - int priority(); + int ordinal(); /** * The remark of interceptor, may be used to generate javadoc. diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java index b9dbe03..4bbf483 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java @@ -130,23 +130,23 @@ public T getService(Class service) { } /** - * 重复添加相同优先级会catch + * 重复添加相同序号会catch * - * @param priority + * @param ordinal * @param interceptor */ - public void addInterceptor(int priority, Class interceptor) { - LogisticsCenter.addInterceptor(priority, interceptor, false); + public void addInterceptor(int ordinal, Class interceptor) { + LogisticsCenter.addInterceptor(ordinal, interceptor, false); } /** - * 重复添加相同优先级会覆盖(更新) + * 重复添加相同序号会覆盖(更新) * - * @param priority + * @param ordinal * @param interceptor */ - public void setInterceptor(int priority, Class interceptor) { - LogisticsCenter.setInterceptor(priority, interceptor); + public void setInterceptor(int ordinal, Class interceptor) { + LogisticsCenter.setInterceptor(ordinal, interceptor); } /** diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java index 82eb321..bae7561 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/LogisticsCenter.java @@ -63,8 +63,6 @@ public static CardMeta getCardMeta(Card card) throws NoFoundRouteException { // Load route and cache it into memory, then delete from metas. if (Warehouse.routeGroups.containsKey(card.getGroup())) { - // If this group is included, but it has not been loaded - // load this group first, because dynamic route has high priority. Warehouse.routeGroups.get(card.getGroup()).load(); Warehouse.routeGroups.remove(card.getGroup()); } @@ -137,43 +135,42 @@ public static T getService(Class serviceClass) { } /** - * 重复添加相同优先级会catch + * 重复添加相同序号会catch * - * @param priority + * @param ordinal * @param interceptor * @param isForce */ - public static void addInterceptor(int priority, Class interceptor, boolean isForce) { + public static void addInterceptor(int ordinal, Class interceptor, boolean isForce) { try { if (isForce) { - Warehouse.interceptors.remove(priority); + Warehouse.interceptors.remove(ordinal); } IInterceptor instance = interceptor.getConstructor().newInstance(); instance.init(); - Warehouse.interceptors.put(priority, instance); + Warehouse.interceptors.put(ordinal, instance); String title = isForce ? "[setInterceptor]" : "[addInterceptor]"; - GoRouter.logger.debug(null, title + " size:" + Warehouse.interceptors.size() + ", priority:" + priority + " -> " + interceptor.getSimpleName()); + GoRouter.logger.debug(null, title + " size:" + Warehouse.interceptors.size() + ", ordinal:" + ordinal + " -> " + interceptor.getSimpleName()); } catch (Exception e) { throw new RouterException("[addInterceptor] " + e.getMessage()); } } /** - * 重复添加相同优先级会覆盖(更新) + * 重复添加相同序号会覆盖(更新) * - * @param priority + * @param ordinal * @param interceptor */ - public static void setInterceptor(int priority, Class interceptor) { - addInterceptor(priority, interceptor, true); + public static void setInterceptor(int ordinal, Class interceptor) { + addInterceptor(ordinal, interceptor, true); } public static void clearInterceptors() { Warehouse.interceptors.clear(); } - /** * 解析参数 * diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java index de63e00..0b6314c 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java @@ -20,6 +20,6 @@ class Warehouse { static final Map, ServiceMeta> services = new ServiceHashMap(); - static final Map interceptors = new InterceptorTreeMap<>("More than one interceptors use same priority [%s]"); + static final Map interceptors = new InterceptorTreeMap<>("More than one interceptors use same ordinal [%s]"); } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java index 8343296..97ad47e 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/DocumentUtils.java @@ -79,7 +79,7 @@ public static void addInterceptorDoc(String moduleName, Logger logger, Element e if (!isDocEnable) return; try { - documentModel.getInterceptors().add(new InterceptorModel(interceptor.priority(), element.toString(), interceptor.remark())); + documentModel.getInterceptors().add(new InterceptorModel(interceptor.ordinal(), element.toString(), interceptor.remark())); } catch (Exception e) { logger.error(moduleName + " Failed to add interceptor [" + element.toString() + "] document, " + e.getMessage()); } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/InterceptorModel.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/InterceptorModel.java index 5530d72..c2a2bf8 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/InterceptorModel.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/doc/model/InterceptorModel.java @@ -2,25 +2,25 @@ public class InterceptorModel { - private int priority; + private int ordinal; private String remark; private String className; public InterceptorModel() { } - public InterceptorModel(int priority, String className, String remark) { - this.priority = priority; + public InterceptorModel(int ordinal, String className, String remark) { + this.ordinal = ordinal; this.className = className; this.remark = remark; } - public int getPriority() { - return priority; + public int getOrdinal() { + return ordinal; } - public void setPriority(int priority) { - this.priority = priority; + public void setOrdinal(int ordinal) { + this.ordinal = ordinal; } public String getRemark() { diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index e8a54cc..e4d604c 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -170,7 +170,7 @@ private void addInterceptor(RoundEnvironment roundEnvironment, MethodSpec.Builde loadIntoMethod.addCode("// add Interceptor\n"); for (Element element : elements) { Interceptor interceptor = element.getAnnotation(Interceptor.class); - loadIntoMethod.addStatement("$T.getInstance().addInterceptor(" + interceptor.priority() + ", $T.class)", mGoRouter, element); + loadIntoMethod.addStatement("$T.getInstance().addInterceptor(" + interceptor.ordinal() + ", $T.class)", mGoRouter, element); DocumentUtils.addInterceptorDoc(moduleName, logger, element, interceptor); } } diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt index 47d5907..03d335d 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt @@ -65,7 +65,7 @@ abstract class GenerateRouteDocTask : DefaultTask() { document!!.interceptors.addAll(documentModel.interceptors) document!!.routes.putAll(documentModel.routes) } - document!!.interceptors.sortBy { interceptor -> interceptor.priority } + document!!.interceptors.sortBy { interceptor -> interceptor.ordinal } } catch (e: Exception) { Logger.e("module[${curProject.name}] route document parsing failed, do not modify the generated route file, use the '${GENERATE_ROUTE_DOC_TASK_NAME}' task to generate a new route document.") } diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/InterceptorModel.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/InterceptorModel.kt index 0feac12..263c95b 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/InterceptorModel.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/model/InterceptorModel.kt @@ -1,7 +1,7 @@ package com.wyjson.router.gradle_plugin.doc.model data class InterceptorModel( - var priority: Int, + var ordinal: Int, var remark: String?, var className: String? ) \ No newline at end of file diff --git a/README.md b/README.md index c9b2243..b91de41 100644 --- a/README.md +++ b/README.md @@ -245,8 +245,8 @@ public class BaseParamActivity extends Activity { ```java // 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查 -// 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行 -@Interceptor(priority = 1, remark = "测试拦截器") +// 拦截器会在跳转之间执行,多个拦截器会按序号从小到大顺序依次执行 +@Interceptor(ordinal = 1, remark = "测试拦截器") public class TestInterceptor implements IInterceptor { @Override public void process(Card card, InterceptorCallback callback) { @@ -489,10 +489,10 @@ GoRouter.getInstance().isRouteRegisterMode(); // 动态注册服务(重复添加相同服务会被覆盖(更新)) GoRouter.getInstance().addService(UserServiceImpl.class); -// 注册拦截器(重复添加相同优先级会catch) +// 注册拦截器(重复添加相同序号会catch) GoRouter.getInstance().addInterceptor(1, TestInterceptor.class); -// 动态注册拦截器(重复添加相同优先级会覆盖(更新)) +// 动态注册拦截器(重复添加相同序号会覆盖(更新)) GoRouter.getInstance().setInterceptor(1, TestInterceptor.class); // 动态注册路由分组,按需加载路由(注意:同一批次仅允许相同group的路由信息注册) @@ -580,8 +580,8 @@ GoRouter { ##### 4. 使用java方式注册拦截器 -* `addInterceptor(priority,interceptor)`重复添加相同优先级会catch。 -* `setInterceptor(priority,interceptor)`重复添加相同优先级会覆盖(更新)。 +* `addInterceptor(ordinal,interceptor)`重复添加相同序号级会catch。 +* `setInterceptor(ordinal,interceptor)`重复添加相同序号会覆盖(更新)。 ##### 5. 混淆 diff --git a/app/GoRouter-route-doc.json b/app/GoRouter-route-doc.json index f6c3058..55c9947 100644 --- a/app/GoRouter-route-doc.json +++ b/app/GoRouter-route-doc.json @@ -18,12 +18,12 @@ }, "interceptors": [ { - "priority": 1, + "ordinal": 1, "remark": "登录拦截器", "className": "com.wyjson.module_user.route.interceptor.SignInInterceptor" }, { - "priority": 100, + "ordinal": 100, "remark": "身份验证拦截器", "className": "com.wyjson.module_user.route.interceptor.AuthenticationInterceptor" } diff --git a/module_user/src/main/java/com/wyjson/module_user/route/interceptor/AuthenticationInterceptor.java b/module_user/src/main/java/com/wyjson/module_user/route/interceptor/AuthenticationInterceptor.java index d9ba395..42a65a8 100644 --- a/module_user/src/main/java/com/wyjson/module_user/route/interceptor/AuthenticationInterceptor.java +++ b/module_user/src/main/java/com/wyjson/module_user/route/interceptor/AuthenticationInterceptor.java @@ -9,7 +9,7 @@ import com.wyjson.router.callback.InterceptorCallback; import com.wyjson.router.interfaces.IInterceptor; -@Interceptor(priority = 100, remark = "身份验证拦截器") +@Interceptor(ordinal = 100, remark = "身份验证拦截器") public class AuthenticationInterceptor implements IInterceptor { @Override diff --git a/module_user/src/main/java/com/wyjson/module_user/route/interceptor/SignInInterceptor.java b/module_user/src/main/java/com/wyjson/module_user/route/interceptor/SignInInterceptor.java index 300bef9..c518c22 100644 --- a/module_user/src/main/java/com/wyjson/module_user/route/interceptor/SignInInterceptor.java +++ b/module_user/src/main/java/com/wyjson/module_user/route/interceptor/SignInInterceptor.java @@ -16,7 +16,7 @@ import com.wyjson.router.callback.InterceptorCallback; import com.wyjson.router.interfaces.IInterceptor; -@Interceptor(priority = 1, remark = "登录拦截器") +@Interceptor(ordinal = 1, remark = "登录拦截器") public class SignInInterceptor implements IInterceptor { @Override From 690be5e3a04bd5011dbeb5bffce800d1fbb0059e Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sun, 12 Nov 2023 13:23:37 +0800 Subject: [PATCH 22/28] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=B1=BB=E5=90=8E=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/wyjson/router/core/RouteModuleLoadCenter.java | 4 ++-- .../compiler/processor/GenerateModuleRouteProcessor.java | 5 ++--- .../java/com/wyjson/router/compiler/utils/Constants.java | 1 + .../com/wyjson/router/gradle_plugin/utils/Constants.kt | 4 ++-- README.md | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java index 0fc674c..c084f9f 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java @@ -108,8 +108,8 @@ private static void markRegisteredByPlugin() { public static final String SEPARATOR = "$$"; // 路由注册生成类所在包名 public static final String ROUTE_MODULE_PACKAGE = "com.wyjson.router.module.route"; - // 路由注册生成类名后缀$$GoRouter - public static final String MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "GoRouter"; + // 路由注册生成类名后缀$$Route + public static final String MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "Route"; private static void loadModuleRouteByDex(Application context) { try { diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java index e4d604c..565719c 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java @@ -29,8 +29,7 @@ import static com.wyjson.router.compiler.utils.Constants.PARAM_NAME_ROUTE_GROUPS; import static com.wyjson.router.compiler.utils.Constants.PARCELABLE_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.PREFIX_OF_LOGGER; -import static com.wyjson.router.compiler.utils.Constants.PROJECT; -import static com.wyjson.router.compiler.utils.Constants.SEPARATOR; +import static com.wyjson.router.compiler.utils.Constants.ROUTE_MODULE_GENERATE_CLASS_NAME_SUFFIX; import static com.wyjson.router.compiler.utils.Constants.SERIALIZABLE_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.SHORT_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.SHORT_PRIMITIVE; @@ -114,7 +113,7 @@ public boolean process(Set set, RoundEnvironment roundEnv DocumentUtils.createDoc(mFiler, moduleName, logger, isGenerateDoc); - String className = generateClassName + SEPARATOR + PROJECT; + String className = generateClassName + ROUTE_MODULE_GENERATE_CLASS_NAME_SUFFIX; MethodSpec.Builder loadIntoMethod = MethodSpec.methodBuilder(METHOD_NAME_LOAD) .addModifiers(PUBLIC) diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java index 739ed14..fa2ba3d 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java @@ -4,6 +4,7 @@ public class Constants { // Generate public static final String PROJECT = "GoRouter"; public static final String SEPARATOR = "$$"; + public static final String ROUTE_MODULE_GENERATE_CLASS_NAME_SUFFIX = SEPARATOR + "Route"; public static final String WARNING_TIPS = "DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY GOROUTER."; public static final String DOCUMENT_FILE_NAME = "route-doc.json"; diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt index 24bc32a..3865be9 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt @@ -12,8 +12,8 @@ object Constants { const val DOCUMENT_FILE_NAME = "route-doc.json" const val _CLASS = ".class" - // 路由注册生成类名后缀$$GoRouter - const val MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "GoRouter" + // 路由注册生成类名后缀$$Route + const val MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "Route" // 需要扫描注入的类,所在的包名 const val SCAN_TARGET_INJECT_PACKAGE_NAME = "$PACKAGE_NAME.module.route" diff --git a/README.md b/README.md index b91de41..f1e0445 100644 --- a/README.md +++ b/README.md @@ -516,12 +516,12 @@ GoRouter.getInstance().build("/user/card/fragment").commitFragment(CardFragment. ##### 7. 自定义模块路由加载 如不使用gradle插件[3-6]进行自动注册,也不想走默认扫描dex的方式,可以不调用`GoRouter.autoLoadModuleRoute(this);`方法,但需要自行调用模块生成的路由加载类。 -模块项目里至少使用一条注解`@Route`、`@Service`、`@Interceptor`,就会生成对应路由表的加载类。路由表加载类命名规则会根据`GOROUTER_MODULE_NAME `设置的模块名称转换成大写驼峰命名+`$$GoRouter.java`,所有模块生成的路由表加载类都会放到`com.wyjson.router.module.route`包下。 -例如模块名称`module_user`会生成`ModuleUser$$GoRouter.java` +模块项目里至少使用一条注解`@Route`、`@Service`、`@Interceptor`,就会生成对应路由表的加载类。路由表加载类命名规则会根据`GOROUTER_MODULE_NAME `设置的模块名称转换成大写驼峰命名+`$$Route.java`,所有模块生成的路由表加载类都会放到`com.wyjson.router.module.route`包下。 +例如模块名称`module_user`会生成`ModuleUser$$Route.java` ```java // 可在任意地方调用模块路由加载类 -new ModuleUser$$GoRouter().load(); +new ModuleUser$$Route().load(); ``` ##### 8. Gradle插件自定义执行的任务 From cc5740ba416ea1a2fe29c135a615833f442d3c59 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sun, 12 Nov 2023 20:15:02 +0800 Subject: [PATCH 23/28] =?UTF-8?q?=E5=A4=9A=E6=A8=A1=E5=9D=97application?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../router/annotation/ApplicationModule.java | 13 ++ .../wyjson/router/annotation/Interceptor.java | 4 +- GoRouter-Api/consumer-rules.pro | 2 + .../main/java/com/wyjson/router/GoRouter.java | 61 ++++- .../router/core/ApplicationModuleCenter.java | 220 ++++++++++++++++++ .../com/wyjson/router/core/Constants.java | 22 ++ ...LoadCenter.java => RouteModuleCenter.java} | 62 +++-- .../com/wyjson/router/core/Warehouse.java | 5 + .../router/interfaces/IApplicationModule.java | 47 ++++ .../com/wyjson/router/utils/PackageUtils.java | 10 +- .../GenerateApplicationModuleProcessor.java | 212 +++++++++++++++++ ...java => GenerateRouteModuleProcessor.java} | 18 +- .../router/compiler/utils/Constants.java | 27 ++- .../gradle/incremental.annotation.processors | 3 +- .../AssembleApplicationModuleCodeInjector.kt | 89 +++++++ .../AssembleApplicationModuleTask.kt | 136 +++++++++++ .../AssembleRouteModuleCodeInjector.kt} | 46 ++-- .../AssembleRouteModuleTask.kt} | 44 ++-- .../gradle_plugin/doc/GenerateRouteDocTask.kt | 20 +- .../launch/GradlePluginLaunch.kt | 37 +-- .../router/gradle_plugin/utils/Constants.kt | 33 ++- .../router/gradle_plugin/utils/Logger.kt | 12 +- README.md | 8 +- .../com/wyjson/go_router/MyApplication.java | 39 +++- gradle.properties | 6 +- .../module_common/CommonApplication.java | 27 +++ .../wyjson/module_main/MainApplication.java | 21 ++ .../wyjson/module_user/UserApplication.java | 21 ++ 28 files changed, 1102 insertions(+), 143 deletions(-) create mode 100644 GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/ApplicationModule.java create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/core/ApplicationModuleCenter.java create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/core/Constants.java rename GoRouter-Api/src/main/java/com/wyjson/router/core/{RouteModuleLoadCenter.java => RouteModuleCenter.java} (60%) create mode 100644 GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IApplicationModule.java create mode 100644 GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateApplicationModuleProcessor.java rename GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/{GenerateModuleRouteProcessor.java => GenerateRouteModuleProcessor.java} (96%) create mode 100644 GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/application/AssembleApplicationModuleCodeInjector.kt create mode 100644 GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/application/AssembleApplicationModuleTask.kt rename GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/{AssembleModuleRouteCodeInjector.kt => route/AssembleRouteModuleCodeInjector.kt} (54%) rename GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/{AssembleModuleRouteTask.kt => route/AssembleRouteModuleTask.kt} (70%) create mode 100644 module_common/src/main/java/com/wyjson/module_common/CommonApplication.java create mode 100644 module_main/src/main/java/com/wyjson/module_main/MainApplication.java create mode 100644 module_user/src/main/java/com/wyjson/module_user/UserApplication.java diff --git a/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/ApplicationModule.java b/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/ApplicationModule.java new file mode 100644 index 0000000..6d34e37 --- /dev/null +++ b/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/ApplicationModule.java @@ -0,0 +1,13 @@ +package com.wyjson.router.annotation; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Target({TYPE}) +@Retention(SOURCE) +public @interface ApplicationModule { + +} \ No newline at end of file diff --git a/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/Interceptor.java b/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/Interceptor.java index c9d11a4..be9a42f 100644 --- a/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/Interceptor.java +++ b/GoRouter-Annotation/src/main/java/com/wyjson/router/annotation/Interceptor.java @@ -9,9 +9,9 @@ @Target({TYPE}) @Retention(SOURCE) public @interface Interceptor { + /** - * The ordinal of interceptor, GoRouter will be execute them follow the ordinal. - * Execute from small to large + * The order of the interceptors will execute them in order from smallest to largest. */ int ordinal(); diff --git a/GoRouter-Api/consumer-rules.pro b/GoRouter-Api/consumer-rules.pro index f36a3da..9616c6a 100644 --- a/GoRouter-Api/consumer-rules.pro +++ b/GoRouter-Api/consumer-rules.pro @@ -6,6 +6,8 @@ } # 自动注册模块路由加载类不混淆 -keep class * implements com.wyjson.router.module.interfaces.IRouteModule +# 自动注册模块Application代理类不混淆 +-keep class * implements com.wyjson.router.interfaces.IApplicationModule # # ########## GoRouter # end ########## diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java index 4bbf483..092a92c 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java @@ -5,6 +5,7 @@ import android.app.Application; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -18,12 +19,14 @@ import com.wyjson.router.callback.GoCallback; import com.wyjson.router.callback.InterceptorCallback; +import com.wyjson.router.core.ApplicationModuleCenter; import com.wyjson.router.core.InterceptorServiceImpl; import com.wyjson.router.core.LogisticsCenter; -import com.wyjson.router.core.RouteModuleLoadCenter; +import com.wyjson.router.core.RouteModuleCenter; import com.wyjson.router.core.interfaces.IInterceptorService; import com.wyjson.router.exception.NoFoundRouteException; import com.wyjson.router.exception.RouterException; +import com.wyjson.router.interfaces.IApplicationModule; import com.wyjson.router.interfaces.IDegradeService; import com.wyjson.router.interfaces.IInterceptor; import com.wyjson.router.interfaces.IPretreatmentService; @@ -65,9 +68,9 @@ public static GoRouter getInstance() { * * @param application */ - public static synchronized void autoLoadModuleRoute(Application application) { - logger.info(null, "[GoRouter] autoLoadModuleRoute!"); - RouteModuleLoadCenter.loadModuleRoute(application); + public static synchronized void autoLoadRouteModule(Application application) { + logger.info(null, "[GoRouter] autoLoadRouteModule!"); + RouteModuleCenter.load(application); } /** @@ -76,7 +79,7 @@ public static synchronized void autoLoadModuleRoute(Application application) { * @return true [GoRouter-Gradle-Plugin] ,false [scan dex file] */ public boolean isRouteRegisterMode() { - return RouteModuleLoadCenter.isRegisterByPlugin(); + return RouteModuleCenter.isRegisterByPlugin(); } public static synchronized void openDebug() { @@ -108,6 +111,54 @@ public static void setLogger(ILogger userLogger) { } } + /** + * 自动加载模块application + * + * @param application + */ + public static synchronized void autoLoadAM(Application application) { + logger.info(null, "[GoRouter] autoLoadAM!"); + ApplicationModuleCenter.load(application); + } + + /** + * 获取模块application注册模式 + * + * @return true [GoRouter-Gradle-Plugin] ,false [scan dex file] + */ + public boolean isAMRegisterMode() { + return ApplicationModuleCenter.isRegisterByPlugin(); + } + + public static void executeAMOnCreate(Application app) { + ApplicationModuleCenter.executeOnCreate(app); + } + + public static void executeAMOnTerminate() { + ApplicationModuleCenter.executeOnTerminate(); + } + + public static void executeAMOnConfigurationChanged(@NonNull Configuration newConfig) { + ApplicationModuleCenter.executeOnConfigurationChanged(newConfig); + } + + public static void executeAMOnLowMemory() { + ApplicationModuleCenter.executeOnLowMemory(); + } + + public static void executeAMOnTrimMemory(int level) { + ApplicationModuleCenter.executeOnTrimMemory(level); + } + + /** + * 动态注册模块application + * + * @param am + */ + public static void registerAM(Class am) { + ApplicationModuleCenter.register(am); + } + /** * 实现相同接口的service会被覆盖(更新) * diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/ApplicationModuleCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/ApplicationModuleCenter.java new file mode 100644 index 0000000..098fc82 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/ApplicationModuleCenter.java @@ -0,0 +1,220 @@ +package com.wyjson.router.core; + +import static com.wyjson.router.core.Constants.APPLICATION_MODULE_NAME_SUFFIX; +import static com.wyjson.router.core.Constants.APPLICATION_MODULE_PACKAGE; +import static com.wyjson.router.core.Constants.GOROUTER_SP_CACHE_KEY; +import static com.wyjson.router.core.Constants.GOROUTER_SP_KEY_APPLICATION_MODULE_MAP; + +import android.app.Application; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Process; + +import androidx.annotation.NonNull; + +import com.wyjson.router.GoRouter; +import com.wyjson.router.exception.RouterException; +import com.wyjson.router.interfaces.IApplicationModule; +import com.wyjson.router.utils.ClassUtils; +import com.wyjson.router.utils.PackageUtils; +import com.wyjson.router.utils.TextUtils; + +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +public class ApplicationModuleCenter { + private static final String TAG = GoRouter.logger.getDefaultTag() + "_AM"; + + private static ListComparator listComparator = new ListComparator(); + + private static boolean registerByPlugin; + + /** + * 获取Application module注册模式 + * + * @return true [GoRouter-Gradle-Plugin] ,false [scan dex file] + */ + public static boolean isRegisterByPlugin() { + return registerByPlugin; + } + + public static synchronized void load(Application application) { + loadByPlugin(); + if (registerByPlugin) { + GoRouter.logger.info(TAG, "Loading mode: Load module application by [GoRouter-Gradle-Plugin] plugin."); + } else { + GoRouter.logger.info(TAG, "Loading mode: The runtime loads the module application by scanning the dex file."); + loadByDex(application); + } + + if (Warehouse.applicationModules.size() == 0) { + GoRouter.logger.error(TAG, "No module application files were found, check your configuration please!"); + } + + if (GoRouter.isDebug()) { + GoRouter.logger.debug(TAG, String.format(Locale.getDefault(), "Module application has already been loaded, ApplicationModuleIndex[%d]", Warehouse.applicationModules.size())); + } + } + + /** + * GoRouter-Gradle-Plugin plugin will generate code inside this method + * call this method to register all module application + */ + public static void loadByPlugin() { + registerByPlugin = false; + // auto generate register code by gradle plugin: GoRouter-Gradle-Plugin + // looks like below: + // register("class name"); + // register("class name"); + } + + private static void register(String className) { + register(className, true); + } + + /** + * register by class name + * Sacrificing a bit of efficiency to solve + * the problem that the main dex file size is too large + */ + private static void register(String className, boolean isPlugin) { + if (!TextUtils.isEmpty(className)) { + try { + Class clazz = Class.forName(className); + Object obj = clazz.getConstructor().newInstance(); + if (obj instanceof IApplicationModule) { + if (isPlugin) { + markRegisteredByPlugin(); + } + register((IApplicationModule) obj); + } else { + GoRouter.logger.error(TAG, + "register failed, class name: " + className + + " should implements one of IApplicationModule."); + } + } catch (RouterException e) { + throw new RouterException("[register] " + e.getMessage()); + } catch (Exception e) { + GoRouter.logger.error(TAG, "register class error:" + className, e); + } + } + } + + /** + * mark already registered by GoRouter-Gradle-Plugin plugin + */ + private static void markRegisteredByPlugin() { + if (!registerByPlugin) { + registerByPlugin = true; + } + } + + private static void loadByDex(Application context) { + try { + long startTime = System.currentTimeMillis(); + Set routeModuleMap; + if (GoRouter.isDebug() || PackageUtils.isNewVersion(context, GOROUTER_SP_CACHE_KEY)) { + GoRouter.logger.info(TAG, "Run with debug mode or new install, rebuild module application."); + // These class was generated by GoRouter-Compiler. + routeModuleMap = ClassUtils.getFileNameByPackageName(context, APPLICATION_MODULE_PACKAGE, APPLICATION_MODULE_NAME_SUFFIX); + if (!routeModuleMap.isEmpty()) { + context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(GOROUTER_SP_KEY_APPLICATION_MODULE_MAP, routeModuleMap).apply(); + } + PackageUtils.updateVersion(context, GOROUTER_SP_CACHE_KEY); // Save new version name when router map update finishes. + } else { + GoRouter.logger.info(TAG, "Load module application from cache."); + routeModuleMap = new HashSet<>(context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(GOROUTER_SP_KEY_APPLICATION_MODULE_MAP, new HashSet())); + } + + GoRouter.logger.info(TAG, "Find the module application loading class for " + routeModuleMap.size() + " modules, cost " + (System.currentTimeMillis() - startTime) + "ms."); + startTime = System.currentTimeMillis(); + + for (String className : routeModuleMap) { + register(className, false); + } + + GoRouter.logger.info(TAG, "The loading module application is complete, cost " + (System.currentTimeMillis() - startTime) + "ms."); + } catch (RouterException e) { + throw new RouterException("[loadByDex] " + e.getMessage()); + } catch (Exception e) { + throw new RouterException("AM [loadByDex] exception! [" + e.getMessage() + "]"); + } + } + + private static void register(IApplicationModule am) { + Warehouse.applicationModules.add(am); + } + + /** + * 动态注册使用 + * + * @param am + */ + public static void register(Class am) { + try { + register(am.getConstructor().newInstance()); + } catch (Exception e) { + GoRouter.logger.error(TAG, "register class error:" + e.getMessage()); + throw new RuntimeException(e); + } + } + + /** + * The priority of interceptor, GoRouter will be execute them follow the priority. + * Execute from large to small + */ + private static class ListComparator implements Comparator { + + @Override + public int compare(IApplicationModule o1, IApplicationModule o2) { + return o2.setPriority() - o1.setPriority(); + } + } + + private interface Consumer { + void execute(IApplicationModule ma); + } + + private static void execute(Consumer consumer) { + if (Warehouse.applicationModules.isEmpty()) { + return; + } + if (listComparator != null) { + Collections.sort(Warehouse.applicationModules, listComparator); + listComparator = null; + } + for (IApplicationModule am : Warehouse.applicationModules) { + consumer.execute(am); + } + } + + public static void executeOnCreate(Application app) { + execute(am -> { + am.onCreate(app); + new Thread(() -> { + // 设置线程的优先级,不与主线程抢资源 + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + am.onLoadAsync(app); + }).start(); + }); + } + + public static void executeOnTerminate() { + execute(IApplicationModule::onTerminate); + } + + public static void executeOnConfigurationChanged(@NonNull Configuration newConfig) { + execute(ma -> ma.onConfigurationChanged(newConfig)); + } + + public static void executeOnLowMemory() { + execute(IApplicationModule::onLowMemory); + } + + public static void executeOnTrimMemory(int level) { + execute(ma -> ma.onTrimMemory(level)); + } +} diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/Constants.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/Constants.java new file mode 100644 index 0000000..2fc29dc --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/Constants.java @@ -0,0 +1,22 @@ +package com.wyjson.router.core; + +class Constants { + + static final String GOROUTER_SP_CACHE_KEY = "SP_GOROUTER_CACHE"; + static final String SEPARATOR = "$$"; + static final String PACKAGE_NAME = "com.wyjson.router"; + + + static final String GOROUTER_SP_KEY_ROUTE_MODULE_MAP = "ROUTE_MODULE_MAP"; + // 路由注册生成类所在包名 + static final String ROUTE_MODULE_PACKAGE = PACKAGE_NAME + ".module.route"; + // 路由注册生成类名后缀$$Route + static final String ROUTE_MODULE_NAME_SUFFIX = SEPARATOR + "Route"; + + + static final String GOROUTER_SP_KEY_APPLICATION_MODULE_MAP = "APPLICATION_MODULE_MAP"; + // 路由注册生成类所在包名 + static final String APPLICATION_MODULE_PACKAGE = PACKAGE_NAME + ".module.application"; + // 路由注册生成类名后缀$$AP + static final String APPLICATION_MODULE_NAME_SUFFIX = SEPARATOR + "AP";// ApplicationProxy +} \ No newline at end of file diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleCenter.java similarity index 60% rename from GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java rename to GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleCenter.java index c084f9f..af9fd05 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleLoadCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/RouteModuleCenter.java @@ -1,5 +1,10 @@ package com.wyjson.router.core; +import static com.wyjson.router.core.Constants.GOROUTER_SP_CACHE_KEY; +import static com.wyjson.router.core.Constants.GOROUTER_SP_KEY_ROUTE_MODULE_MAP; +import static com.wyjson.router.core.Constants.ROUTE_MODULE_NAME_SUFFIX; +import static com.wyjson.router.core.Constants.ROUTE_MODULE_PACKAGE; + import android.app.Application; import android.content.Context; @@ -14,7 +19,8 @@ import java.util.Locale; import java.util.Set; -public class RouteModuleLoadCenter { +public class RouteModuleCenter { + private static final String TAG = GoRouter.logger.getDefaultTag() + "_RM"; private static boolean registerByPlugin; @@ -27,22 +33,22 @@ public static boolean isRegisterByPlugin() { return registerByPlugin; } - public static synchronized void loadModuleRoute(Application application) { - loadModuleRouteByPlugin(); + public static synchronized void load(Application application) { + loadByPlugin(); if (registerByPlugin) { - GoRouter.logger.info(null, "Loading mode: Load routes by [GoRouter-Gradle-Plugin] plugin."); + GoRouter.logger.info(TAG, "Loading mode: Load routes by [GoRouter-Gradle-Plugin] plugin."); } else { - GoRouter.logger.info(null, "Loading mode: The runtime loads the route by scanning the dex file."); - loadModuleRouteByDex(application); + GoRouter.logger.info(TAG, "Loading mode: The runtime loads the route by scanning the dex file."); + loadByDex(application); } if (Warehouse.routeGroups.size() == 0) { - GoRouter.logger.error(null, "No mapping files were found, check your configuration please!"); + GoRouter.logger.error(TAG, "No route files were found, check your configuration please!"); } if (GoRouter.isDebug()) { - GoRouter.logger.debug(null, String.format(Locale.getDefault(), - "GoRouter has already been loaded, RouteGroupIndex[%d], ServiceIndex[%d], InterceptorIndex[%d]", + GoRouter.logger.debug(TAG, String.format(Locale.getDefault(), + "Route has already been loaded, RouteGroupIndex[%d], ServiceIndex[%d], InterceptorIndex[%d]", Warehouse.routeGroups.size(), Warehouse.services.size(), Warehouse.interceptors.size() @@ -54,7 +60,7 @@ public static synchronized void loadModuleRoute(Application application) { * GoRouter-Gradle-Plugin plugin will generate code inside this method * call this method to register all Routes, Interceptors and Services */ - private static void loadModuleRouteByPlugin() { + private static void loadByPlugin() { registerByPlugin = false; // auto generate register code by gradle plugin: GoRouter-Gradle-Plugin // looks like below: @@ -82,14 +88,14 @@ private static void register(String className, boolean isPlugin) { } ((IRouteModule) obj).load(); } else { - GoRouter.logger.error(null, + GoRouter.logger.error(TAG, "register failed, class name: " + className + " should implements one of IRouteModule."); } } catch (RouterException e) { throw new RouterException("[register] " + e.getMessage()); } catch (Exception e) { - GoRouter.logger.error(null, "register class error:" + className, e); + GoRouter.logger.error(TAG, "register class error:" + className, e); } } } @@ -103,43 +109,35 @@ private static void markRegisteredByPlugin() { } } - public static final String GOROUTER_SP_CACHE_KEY = "SP_GOROUTER_CACHE"; - public static final String GOROUTER_SP_KEY_MAP = "ROUTE_MODULE_MAP"; - public static final String SEPARATOR = "$$"; - // 路由注册生成类所在包名 - public static final String ROUTE_MODULE_PACKAGE = "com.wyjson.router.module.route"; - // 路由注册生成类名后缀$$Route - public static final String MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "Route"; - - private static void loadModuleRouteByDex(Application context) { + private static void loadByDex(Application context) { try { long startTime = System.currentTimeMillis(); Set routeModuleMap; - if (GoRouter.isDebug() || PackageUtils.isNewVersion(context)) { - GoRouter.logger.info(null, "Run with debug mode or new install, rebuild router map."); + if (GoRouter.isDebug() || PackageUtils.isNewVersion(context, GOROUTER_SP_CACHE_KEY)) { + GoRouter.logger.info(TAG, "Run with debug mode or new install, rebuild router map."); // These class was generated by GoRouter-Compiler. - routeModuleMap = ClassUtils.getFileNameByPackageName(context, ROUTE_MODULE_PACKAGE, MODULE_ROUTE_NAME_SUFFIX); + routeModuleMap = ClassUtils.getFileNameByPackageName(context, ROUTE_MODULE_PACKAGE, ROUTE_MODULE_NAME_SUFFIX); if (!routeModuleMap.isEmpty()) { - context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(GOROUTER_SP_KEY_MAP, routeModuleMap).apply(); + context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(GOROUTER_SP_KEY_ROUTE_MODULE_MAP, routeModuleMap).apply(); } - PackageUtils.updateVersion(context); // Save new version name when router map update finishes. + PackageUtils.updateVersion(context, GOROUTER_SP_CACHE_KEY); // Save new version name when router map update finishes. } else { - GoRouter.logger.info(null, "Load router map from cache."); - routeModuleMap = new HashSet<>(context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(GOROUTER_SP_KEY_MAP, new HashSet())); + GoRouter.logger.info(TAG, "Load router map from cache."); + routeModuleMap = new HashSet<>(context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(GOROUTER_SP_KEY_ROUTE_MODULE_MAP, new HashSet())); } - GoRouter.logger.info(null, "Find the route loading class for " + routeModuleMap.size() + " modules, cost " + (System.currentTimeMillis() - startTime) + "ms."); + GoRouter.logger.info(TAG, "Find the route loading class for " + routeModuleMap.size() + " modules, cost " + (System.currentTimeMillis() - startTime) + "ms."); startTime = System.currentTimeMillis(); for (String className : routeModuleMap) { register(className, false); } - GoRouter.logger.info(null, "The loading module route is complete, cost " + (System.currentTimeMillis() - startTime) + "ms."); + GoRouter.logger.info(TAG, "The loading module route is complete, cost " + (System.currentTimeMillis() - startTime) + "ms."); } catch (RouterException e) { - throw new RouterException("[loadModuleRouteByDex] " + e.getMessage()); + throw new RouterException("[loadByDex] " + e.getMessage()); } catch (Exception e) { - throw new RouterException("GoRouter [loadModuleRouteByDex] exception! [" + e.getMessage() + "]"); + throw new RouterException("GoRouter [loadByDex] exception! [" + e.getMessage() + "]"); } } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java index 0b6314c..5c7bede 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/Warehouse.java @@ -1,6 +1,7 @@ package com.wyjson.router.core; import com.wyjson.router.interfaces.IInterceptor; +import com.wyjson.router.interfaces.IApplicationModule; import com.wyjson.router.interfaces.IService; import com.wyjson.router.model.CardMeta; import com.wyjson.router.model.ServiceMeta; @@ -10,10 +11,14 @@ import com.wyjson.router.utils.RouteHashMap; import com.wyjson.router.utils.ServiceHashMap; +import java.util.ArrayList; +import java.util.List; import java.util.Map; class Warehouse { + static final List applicationModules = new ArrayList<>(); + static final Map routeGroups = new RouteGroupHashMap(); static final Map routes = new RouteHashMap(); diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IApplicationModule.java b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IApplicationModule.java new file mode 100644 index 0000000..441a676 --- /dev/null +++ b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IApplicationModule.java @@ -0,0 +1,47 @@ +package com.wyjson.router.interfaces; + +import android.app.Application; +import android.content.res.Configuration; + +import androidx.annotation.NonNull; + +public interface IApplicationModule { + + int PRIORITY_MAX = 100; + int PRIORITY_NORM = 50; + int PRIORITY_MIN = 1; + + /** + * The priority of the module application, + * which will execute them in order from largest to smallest execution. + */ + default int setPriority() { + return PRIORITY_NORM; + } + + void onCreate(Application app); + + /** + * 优化启动速度,一些不着急的初始化可以放在这里做,子线程 + * + * @param app + */ + void onLoadAsync(Application app); + + default void onTerminate() { + + } + + default void onConfigurationChanged(@NonNull Configuration newConfig) { + + } + + default void onLowMemory() { + + } + + default void onTrimMemory(int level) { + + } + +} diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/utils/PackageUtils.java b/GoRouter-Api/src/main/java/com/wyjson/router/utils/PackageUtils.java index d8ab92f..efd5e5f 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/utils/PackageUtils.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/utils/PackageUtils.java @@ -1,7 +1,5 @@ package com.wyjson.router.utils; -import static com.wyjson.router.core.RouteModuleLoadCenter.GOROUTER_SP_CACHE_KEY; - import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageInfo; @@ -16,13 +14,13 @@ public class PackageUtils { private static String NEW_VERSION_NAME; private static int NEW_VERSION_CODE; - public static boolean isNewVersion(Context context) { + public static boolean isNewVersion(Context context, String spName) { PackageInfo packageInfo = getPackageInfo(context); if (null != packageInfo) { String versionName = packageInfo.versionName; int versionCode = packageInfo.versionCode; - SharedPreferences sp = context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE); + SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE); if (!versionName.equals(sp.getString(LAST_VERSION_NAME, null)) || versionCode != sp.getInt(LAST_VERSION_CODE, -1)) { // new version NEW_VERSION_NAME = versionName; @@ -37,9 +35,9 @@ public static boolean isNewVersion(Context context) { } } - public static void updateVersion(Context context) { + public static void updateVersion(Context context, String spName) { if (!android.text.TextUtils.isEmpty(NEW_VERSION_NAME) && NEW_VERSION_CODE != 0) { - SharedPreferences sp = context.getSharedPreferences(GOROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE); + SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE); sp.edit().putString(LAST_VERSION_NAME, NEW_VERSION_NAME).putInt(LAST_VERSION_CODE, NEW_VERSION_CODE).apply(); } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateApplicationModuleProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateApplicationModuleProcessor.java new file mode 100644 index 0000000..e47585c --- /dev/null +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateApplicationModuleProcessor.java @@ -0,0 +1,212 @@ +package com.wyjson.router.compiler.processor; + +import static com.wyjson.router.compiler.utils.Constants.APPLICATION; +import static com.wyjson.router.compiler.utils.Constants.APPLICATION_MODULE_GENERATE_CLASS_NAME_SUFFIX; +import static com.wyjson.router.compiler.utils.Constants.APPLICATION_MODULE_PACKAGE_NAME; +import static com.wyjson.router.compiler.utils.Constants.CONFIGURATION; +import static com.wyjson.router.compiler.utils.Constants.CONTEXT; +import static com.wyjson.router.compiler.utils.Constants.FIELD_MAM; +import static com.wyjson.router.compiler.utils.Constants.I_APPLICATION_MODULE_PACKAGE_NAME; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_ON_CONFIGURATION_CHANGED; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_ON_CREATE; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_ON_LOAD_ASYNC; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_ON_LOW_MEMORY; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_ON_TERMINATE; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_ON_TRIM_MEMORY; +import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_SET_PRIORITY; +import static com.wyjson.router.compiler.utils.Constants.NONNULL; +import static com.wyjson.router.compiler.utils.Constants.PREFIX_OF_LOGGER; +import static com.wyjson.router.compiler.utils.Constants.WARNING_TIPS; +import static javax.lang.model.element.Modifier.FINAL; +import static javax.lang.model.element.Modifier.PRIVATE; +import static javax.lang.model.element.Modifier.PUBLIC; + +import com.google.auto.service.AutoService; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import com.wyjson.router.annotation.ApplicationModule; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; + +@AutoService(Processor.class) +public class GenerateApplicationModuleProcessor extends BaseProcessor { + + TypeMirror mApplication; + TypeMirror mContext; + TypeMirror mConfiguration; + TypeElement mNONNULL; + TypeElement mIApplicationModule; + + @Override + public Set getSupportedAnnotationTypes() { + Set set = new LinkedHashSet<>(); + set.add(ApplicationModule.class.getCanonicalName()); + return set; + } + + @Override + public synchronized void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + logger.info(moduleName + " >>> GenerateApplicationModuleProcessor init. <<<"); + mApplication = elementUtils.getTypeElement(APPLICATION).asType(); + mContext = elementUtils.getTypeElement(CONTEXT).asType(); + mConfiguration = elementUtils.getTypeElement(CONFIGURATION).asType(); + mNONNULL = elementUtils.getTypeElement(NONNULL); + mIApplicationModule = elementUtils.getTypeElement(I_APPLICATION_MODULE_PACKAGE_NAME); + } + + @Override + public boolean process(Set set, RoundEnvironment roundEnvironment) { + if (CollectionUtils.isEmpty(set)) + return false; + + Set elements = roundEnvironment.getElementsAnnotatedWith(ApplicationModule.class); + if (CollectionUtils.isEmpty(elements)) + return false; + + logger.info(moduleName + " >>> Found ApplicationModule, size is " + elements.size() + " <<<"); + + for (Element element : elements) { + verify(element); + String applicationModuleClassName = ((TypeElement) element).getQualifiedName().toString(); + String className = String.format(APPLICATION_MODULE_GENERATE_CLASS_NAME_SUFFIX, generateClassName, element.getSimpleName().toString()); + TypeSpec.Builder thisClass = TypeSpec.classBuilder(className) + .addModifiers(PUBLIC) + .addSuperinterface(ClassName.get(mIApplicationModule)) + .addJavadoc(WARNING_TIPS); + + setConstructorMethod(thisClass, element); + setSetPriorityMethod(thisClass, element); + setOnCreateMethod(thisClass, element); + setOnLoadAsyncMethod(thisClass, element); + setOnTerminateMethod(thisClass, element); + setOnConfigurationChangedMethod(thisClass, element); + setOnLowMemoryMethod(thisClass, element); + setOnTrimMemoryMethod(thisClass, element); + + try { + JavaFile.builder(APPLICATION_MODULE_PACKAGE_NAME, thisClass.build()).indent(" ").build().writeTo(mFiler); + logger.info(moduleName + " class[" + applicationModuleClassName + "], Success to generate [" + className + "] class."); + } catch (IOException e) { + logger.error(moduleName + "class[" + applicationModuleClassName + "], Failed to generate [" + className + "] class!"); + logger.error(e); + } + } + + logger.info(moduleName + " >>> GenerateApplicationModuleProcessor over. <<<"); + return true; + } + + private void setConstructorMethod(TypeSpec.Builder thisClass, Element element) { + thisClass.addField(ClassName.get(mIApplicationModule), FIELD_MAM, PRIVATE, FINAL) + .addMethod(MethodSpec.constructorBuilder().addModifiers(PUBLIC).addStatement("this.$N = new $T()", FIELD_MAM, element).build()); + } + + private void setSetPriorityMethod(TypeSpec.Builder thisClass, Element element) { + MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_SET_PRIORITY) + .addModifiers(PUBLIC) + .returns(int.class) + .addAnnotation(Override.class) + .addStatement("return this.$N.$N()", FIELD_MAM, METHOD_NAME_SET_PRIORITY); + thisClass.addMethod(method.build()); + } + + private void setOnCreateMethod(TypeSpec.Builder thisClass, Element element) { + MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_ON_CREATE) + .addModifiers(PUBLIC) + .addAnnotation(Override.class) + .addParameter(TypeName.get(mApplication), "app") + .addStatement("this.$N.$N($N)", FIELD_MAM, METHOD_NAME_ON_CREATE, "app"); + thisClass.addMethod(method.build()); + } + + private void setOnLoadAsyncMethod(TypeSpec.Builder thisClass, Element element) { + MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_ON_LOAD_ASYNC) + .addModifiers(PUBLIC) + .addAnnotation(Override.class) + .addParameter(TypeName.get(mApplication), "app") + .addStatement("this.$N.$N($N)", FIELD_MAM, METHOD_NAME_ON_LOAD_ASYNC, "app"); + thisClass.addMethod(method.build()); + } + + private void setOnTerminateMethod(TypeSpec.Builder thisClass, Element element) { + MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_ON_TERMINATE) + .addModifiers(PUBLIC) + .addAnnotation(Override.class) + .addStatement("this.$N.$N()", FIELD_MAM, METHOD_NAME_ON_TERMINATE); + thisClass.addMethod(method.build()); + } + + private void setOnConfigurationChangedMethod(TypeSpec.Builder thisClass, Element element) { + ParameterSpec newConfigParamSpec = ParameterSpec + .builder(TypeName.get(mConfiguration), "newConfig") + .addAnnotation(ClassName.get(mNONNULL)) + .build(); + MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_ON_CONFIGURATION_CHANGED) + .addModifiers(PUBLIC) + .addAnnotation(Override.class) +// .addParameter(TypeName.get(mConfiguration), "newConfig") + .addParameter(newConfigParamSpec) + .addStatement("this.$N.$N($N)", FIELD_MAM, METHOD_NAME_ON_CONFIGURATION_CHANGED, "newConfig"); + thisClass.addMethod(method.build()); + } + + private void setOnLowMemoryMethod(TypeSpec.Builder thisClass, Element element) { + MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_ON_LOW_MEMORY) + .addModifiers(PUBLIC) + .addAnnotation(Override.class) + .addStatement("this.$N.$N()", FIELD_MAM, METHOD_NAME_ON_LOW_MEMORY); + thisClass.addMethod(method.build()); + } + + private void setOnTrimMemoryMethod(TypeSpec.Builder thisClass, Element element) { + MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_ON_TRIM_MEMORY) + .addModifiers(PUBLIC) + .addAnnotation(Override.class) + .addParameter(int.class, "level") + .addStatement("this.$N.$N($N)", FIELD_MAM, METHOD_NAME_ON_TRIM_MEMORY, "level"); + thisClass.addMethod(method.build()); + } + + private void verify(Element element) { + // 检查注解只能在class类上使用,不能在接口等其他地方使用. + if (!element.getKind().isClass()) { + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " '@ApplicationModule' Annotation can only be used in class."); + } + TypeElement typeElement = (TypeElement) element; + + // 检查使用该注解的类,必须同时要实现IApplicationModule接口 + List mirrorList = typeElement.getInterfaces(); + boolean isExistIApplicationModule = false; + if (!mirrorList.isEmpty()) { + for (TypeMirror mirror : mirrorList) { + if (StringUtils.equals(I_APPLICATION_MODULE_PACKAGE_NAME, mirror.toString())) { + isExistIApplicationModule = true; + break; + } + } + } + if (!isExistIApplicationModule) { + String applicationModuleClassName = typeElement.getQualifiedName().toString(); + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " class[" + applicationModuleClassName + "] must implements interface[" + I_APPLICATION_MODULE_PACKAGE_NAME + "]"); + } + } + +} diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateRouteModuleProcessor.java similarity index 96% rename from GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java rename to GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateRouteModuleProcessor.java index 565719c..8615bc5 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateModuleRouteProcessor.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateRouteModuleProcessor.java @@ -12,7 +12,7 @@ import static com.wyjson.router.compiler.utils.Constants.FLOAT_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.FLOAT_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.FRAGMENT; -import static com.wyjson.router.compiler.utils.Constants.GOROUTER_PACKAGE_NAME; +import static com.wyjson.router.compiler.utils.Constants.GOROUTER; import static com.wyjson.router.compiler.utils.Constants.INTEGER_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.INTEGER_PRIMITIVE; import static com.wyjson.router.compiler.utils.Constants.I_ROUTE_MODULE_GROUP_METHOD_NAME_LOAD; @@ -25,7 +25,7 @@ import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP; import static com.wyjson.router.compiler.utils.Constants.METHOD_NAME_LOAD_ROUTE_GROUP; -import static com.wyjson.router.compiler.utils.Constants.MODULE_PACKAGE_NAME; +import static com.wyjson.router.compiler.utils.Constants.ROUTE_MODULE_PACKAGE_NAME; import static com.wyjson.router.compiler.utils.Constants.PARAM_NAME_ROUTE_GROUPS; import static com.wyjson.router.compiler.utils.Constants.PARCELABLE_PACKAGE; import static com.wyjson.router.compiler.utils.Constants.PREFIX_OF_LOGGER; @@ -75,7 +75,7 @@ import javax.lang.model.type.TypeMirror; @AutoService(Processor.class) -public class GenerateModuleRouteProcessor extends BaseProcessor { +public class GenerateRouteModuleProcessor extends BaseProcessor { TypeElement mGoRouter; TypeElement mIRouteModule; @@ -101,8 +101,8 @@ public Set getSupportedAnnotationTypes() { @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); - logger.info(moduleName + " >>> GenerateModuleRouteProcessor init. <<<"); - mGoRouter = elementUtils.getTypeElement(GOROUTER_PACKAGE_NAME); + logger.info(moduleName + " >>> GenerateRouteModuleProcessor init. <<<"); + mGoRouter = elementUtils.getTypeElement(GOROUTER); mIRouteModule = elementUtils.getTypeElement(I_ROUTE_MODULE_PACKAGE_NAME); } @@ -125,7 +125,7 @@ public boolean process(Set set, RoundEnvironment roundEnv LinkedHashSet routeGroupMethods = addRouteGroup(roundEnvironment, loadIntoMethod); try { - JavaFile.builder(MODULE_PACKAGE_NAME, + JavaFile.builder(ROUTE_MODULE_PACKAGE_NAME, TypeSpec.classBuilder(className) .addModifiers(PUBLIC) .addSuperinterface(ClassName.get(mIRouteModule)) @@ -136,7 +136,7 @@ public boolean process(Set set, RoundEnvironment roundEnv .indent(" ") .build() .writeTo(mFiler); - logger.info(moduleName + " >>> GenerateModuleRouteProcessor over. <<<"); + logger.info(moduleName + " >>> GenerateRouteModuleProcessor over. <<<"); } catch (IOException e) { logger.error(moduleName + " Failed to generate [" + className + "] class!"); logger.error(e); @@ -273,7 +273,7 @@ private String extractRouteGroup(String path) { try { String group = path.substring(1, path.indexOf("/", 1)); if (StringUtils.isEmpty(group)) { - throw new RuntimeException("Extract the default group failed! There's nothing between 2 '/'!"); + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " Extract the default group failed! There's nothing between 2 '/'!"); } return group; } catch (Exception e) { @@ -377,7 +377,7 @@ private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element eleme } else if (types.isSubtype(typeMirror, serializableType)) { paramType = "putSerializable"; } else { - throw new RuntimeException("@Param(type='" + typeMirror + "') is marked as an unsupported type"); + throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " @Param(type='" + typeMirror + "') is marked as an unsupported type"); } } diff --git a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java index fa2ba3d..0691ae1 100644 --- a/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java +++ b/GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/utils/Constants.java @@ -4,6 +4,7 @@ public class Constants { // Generate public static final String PROJECT = "GoRouter"; public static final String SEPARATOR = "$$"; + // ModuleName$$Route public static final String ROUTE_MODULE_GENERATE_CLASS_NAME_SUFFIX = SEPARATOR + "Route"; public static final String WARNING_TIPS = "DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY GOROUTER."; public static final String DOCUMENT_FILE_NAME = "route-doc.json"; @@ -11,12 +12,16 @@ public class Constants { // System interface public static final String ACTIVITY = "android.app.Activity"; public static final String FRAGMENT = "androidx.fragment.app.Fragment"; + public static final String APPLICATION = "android.app.Application"; + public static final String CONTEXT = "android.content.Context"; + public static final String CONFIGURATION = "android.content.res.Configuration"; + public static final String NONNULL = "androidx.annotation.NonNull"; public static final String PACKAGE_NAME = "com.wyjson.router"; public static final String DOCS_PACKAGE_NAME = PACKAGE_NAME + ".docs"; - public static final String GOROUTER_PACKAGE_NAME = PACKAGE_NAME + ".GoRouter"; + public static final String GOROUTER = PACKAGE_NAME + ".GoRouter"; - public static final String MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module.route"; + public static final String ROUTE_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module.route"; public static final String I_ROUTE_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module.interfaces.IRouteModule"; public static final String METHOD_NAME_LOAD = "load"; public static final String METHOD_NAME_LOAD_ROUTE_FOR_x_GROUP = "loadRouteFor%sGroup"; @@ -71,4 +76,22 @@ public class Constants { public static final String BOOLEAN_PRIMITIVE = "boolean"; public static final String CHAR_PRIMITIVE = "char"; + + /** + * Application Module + */ + // ModuleName$$className$$AP(ApplicationProxy) + public static final String APPLICATION_MODULE_GENERATE_CLASS_NAME_SUFFIX = "%s" + SEPARATOR + "%s" + SEPARATOR + "AP"; + public static final String APPLICATION_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".module.application"; + public static final String I_APPLICATION_MODULE_PACKAGE_NAME = PACKAGE_NAME + ".interfaces.IApplicationModule"; + public static final String FIELD_MAM = "mAM";// mApplicationModule + public static final String METHOD_NAME_SET_PRIORITY = "setPriority"; + public static final String METHOD_NAME_ON_CREATE = "onCreate"; + public static final String METHOD_NAME_ON_LOAD_ASYNC = "onLoadAsync"; + public static final String METHOD_NAME_ON_TERMINATE = "onTerminate"; + public static final String METHOD_NAME_ON_CONFIGURATION_CHANGED= "onConfigurationChanged"; + public static final String METHOD_NAME_ON_LOW_MEMORY = "onLowMemory"; + public static final String METHOD_NAME_ON_TRIM_MEMORY = "onTrimMemory"; + + } \ No newline at end of file diff --git a/GoRouter-Compiler/src/main/resources/META-INF/gradle/incremental.annotation.processors b/GoRouter-Compiler/src/main/resources/META-INF/gradle/incremental.annotation.processors index 4b97163..ae6059d 100644 --- a/GoRouter-Compiler/src/main/resources/META-INF/gradle/incremental.annotation.processors +++ b/GoRouter-Compiler/src/main/resources/META-INF/gradle/incremental.annotation.processors @@ -1 +1,2 @@ -com.wyjson.router.compiler.processor.GenerateModuleRouteProcessor,aggregating \ No newline at end of file +com.wyjson.router.compiler.processor.GenerateRouteModuleProcessor,aggregating +com.wyjson.router.compiler.processor.GenerateApplicationModuleProcessor,aggregating \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/application/AssembleApplicationModuleCodeInjector.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/application/AssembleApplicationModuleCodeInjector.kt new file mode 100644 index 0000000..c37e461 --- /dev/null +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/application/AssembleApplicationModuleCodeInjector.kt @@ -0,0 +1,89 @@ +package com.wyjson.router.gradle_plugin.core.application + +import com.wyjson.router.gradle_plugin.utils.Constants +import com.wyjson.router.gradle_plugin.utils.Constants.APPLICATION_MODULE_INJECT_CLASS_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.APPLICATION_MODULE_INJECT_METHOD_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.APPLICATION_MODULE_INJECT_TARGET_METHOD_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.APPLICATION_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME +import com.wyjson.router.gradle_plugin.utils.Constants._CLASS +import com.wyjson.router.gradle_plugin.utils.Logger +import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.ClassWriter +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes +import org.objectweb.asm.commons.AdviceAdapter +import java.io.InputStream + +class AssembleApplicationModuleCodeInjector(val routeModuleClassList: List) { + + private val TAG = "AM" + + fun execute(inputStream: InputStream): ByteArray { + Logger.i(TAG, "Start execute ASM method") + val classReader = ClassReader(inputStream) + val classWriter = ClassWriter(ClassWriter.COMPUTE_MAXS) + val classVisitor = AssembleRouteModuleClassVisitor(classWriter) + classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES) + return classWriter.toByteArray() + } + + inner class AssembleRouteModuleClassVisitor(private val mClassVisitor: ClassVisitor) : + ClassVisitor(Opcodes.ASM9, mClassVisitor) { + + override fun visitMethod( + access: Int, + name: String?, + desc: String?, + signature: String?, + exception: Array? + ): MethodVisitor { + var mv = mClassVisitor.visitMethod(access, name, desc, signature, exception) + if (APPLICATION_MODULE_INJECT_METHOD_NAME == name) { + mv = AssembleRouteModuleMethodAdapter(mv, access, name, desc) + } + return mv + } + } + + inner class AssembleRouteModuleMethodAdapter( + mv: MethodVisitor, + access: Int, + name: String, + desc: String? + ) : AdviceAdapter(Opcodes.ASM9, mv, access, name, desc) { + + override fun visitInsn(opcode: Int) { + if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) { + if (routeModuleClassList.isNotEmpty()) { + val injectClassName = APPLICATION_MODULE_INJECT_CLASS_NAME + Logger.i(TAG, "Start inject the [${injectClassName}.${APPLICATION_MODULE_INJECT_METHOD_NAME}]") + } else { + Logger.w(TAG, "No need for an inject!") + } + routeModuleClassList.forEach { routeModuleClassName -> + val name = Constants.slashToDot(APPLICATION_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME) + "." + routeModuleClassName.replace(_CLASS, "") + Logger.i(TAG, "inject the [${APPLICATION_MODULE_INJECT_TARGET_METHOD_NAME}(\"${name}\")]") + mv.visitLdcInsn(name) + mv.visitMethodInsn( + INVOKESTATIC, + Constants.dotToSlash(APPLICATION_MODULE_INJECT_CLASS_NAME), + APPLICATION_MODULE_INJECT_TARGET_METHOD_NAME, + "(Ljava/lang/String;)V", + false + ) + } + } + super.visitInsn(opcode) + } + + override fun visitMaxs(maxStack: Int, maxLocals: Int) { + super.visitMaxs(maxStack + 4, maxLocals) + } + + override fun onMethodExit(opcode: Int) { + super.onMethodExit(opcode) + Logger.i(TAG, "End of method inject") + } + } +} \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/application/AssembleApplicationModuleTask.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/application/AssembleApplicationModuleTask.kt new file mode 100644 index 0000000..49490aa --- /dev/null +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/application/AssembleApplicationModuleTask.kt @@ -0,0 +1,136 @@ +package com.wyjson.router.gradle_plugin.core.application + +import com.wyjson.router.gradle_plugin.utils.Constants +import com.wyjson.router.gradle_plugin.utils.Constants.APPLICATION_MODULE_NAME_SUFFIX +import com.wyjson.router.gradle_plugin.utils.Constants.APPLICATION_MODULE_INJECT_CLASS_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.APPLICATION_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME +import com.wyjson.router.gradle_plugin.utils.Constants._CLASS +import com.wyjson.router.gradle_plugin.utils.Logger +import org.gradle.api.DefaultTask +import org.gradle.api.file.Directory +import org.gradle.api.file.RegularFile +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import java.io.BufferedOutputStream +import java.io.ByteArrayInputStream +import java.io.File +import java.io.FileOutputStream +import java.util.jar.JarEntry +import java.util.jar.JarFile +import java.util.jar.JarOutputStream +import java.util.zip.ZipException +import kotlin.system.measureTimeMillis + +abstract class AssembleApplicationModuleTask : DefaultTask() { + + private val TAG = "AM" + + @get:InputFiles + abstract val allJars: ListProperty + + @get:InputFiles + abstract val allDirectories: ListProperty + + @get:OutputFile + abstract val output: RegularFileProperty + + private val applicationModuleClassList = ArrayList() + private var originInject: ByteArray? = null + private var jarOutput: JarOutputStream? = null + + @TaskAction + fun taskAction() { + jarOutput = JarOutputStream(BufferedOutputStream(FileOutputStream(output.get().asFile))) + val scanTimeCost = measureTimeMillis { + scanFile() + } + Logger.i(TAG, "Scan finish, current cost time ${scanTimeCost}ms") + + if (originInject == null) { + Logger.e(TAG, "Can not find GoRouter inject point, Do you import [GoRouter-Api]???") + return + } + val injectCodeTimeCost = measureTimeMillis { + injectCode() + } + Logger.i(TAG, "Inject code finish, current cost time ${injectCodeTimeCost}ms") + } + + private fun scanFile() { + allDirectories.get().forEach { directory -> +// Logger.i("Scan to directory [${directory.asFile.absolutePath}]") + directory.asFile.walk().forEach { file -> + if (file.isFile) { + if (file.name.endsWith(APPLICATION_MODULE_NAME_SUFFIX + _CLASS)) { + Logger.i(TAG, "Scan to class [${file.name}] be from directory [${directory.asFile.absolutePath}]") + applicationModuleClassList.add(file.name) + } + val relativePath = directory.asFile.toURI().relativize(file.toURI()).path +// Logger.i("Scan the classes in the directory [${relativePath.replace(File.separatorChar, '.')}]") + jarOutput!!.putNextEntry(JarEntry(relativePath.replace(File.separatorChar, '/'))) + file.inputStream().use { inputStream -> + inputStream.copyTo(jarOutput!!) + } + jarOutput!!.closeEntry() + } + } + } + + val tempList = ArrayList() + allJars.get().forEach { file -> + tempList.clear() +// Logger.i("Scan to jar [${file.asFile.absolutePath}]") + val jarFile = JarFile(file.asFile) + val enumeration = jarFile.entries() + while (enumeration.hasMoreElements()) { + val jarEntry = enumeration.nextElement() + try { + val entryName = jarEntry.name + if (jarEntry.isDirectory || jarEntry.name.isEmpty()) { + continue + } + if (Constants.dotToSlash(APPLICATION_MODULE_INJECT_CLASS_NAME) + _CLASS == entryName) { + Logger.i(TAG, "Find the inject class [$entryName]") + jarFile.getInputStream(jarEntry).use { inputs -> + originInject = inputs.readAllBytes() + } + } else { + val startsWith = entryName.startsWith(Constants.dotToSlash(APPLICATION_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME)) + val endsWith = entryName.endsWith(Constants.dotToSlash(APPLICATION_MODULE_NAME_SUFFIX) + _CLASS) + if (startsWith && endsWith) { + val className = entryName.substring(entryName.lastIndexOf("/") + 1) + Logger.i(TAG, "Scan to class [$className] be from jar [${file.asFile.absolutePath}]") + if (className.isNotEmpty()) { + tempList.add(className) + } + } + jarOutput!!.putNextEntry(JarEntry(jarEntry.name)) + jarFile.getInputStream(jarEntry).use { + it.copyTo(jarOutput!!) + } + jarOutput!!.closeEntry() + } + } catch (e: Exception) { + if (!(e is ZipException && e.message?.startsWith("duplicate entry:") == true)) { + Logger.w(TAG, "Merge jar error entry:[${jarEntry.name}], error message:$e") + } + } + } + applicationModuleClassList.addAll(tempList) + jarFile.close() + } + } + + private fun injectCode() { + val resultByteArray = AssembleApplicationModuleCodeInjector(applicationModuleClassList).execute(ByteArrayInputStream(originInject)) + jarOutput!!.putNextEntry(JarEntry(Constants.dotToSlash(APPLICATION_MODULE_INJECT_CLASS_NAME) + _CLASS)) + ByteArrayInputStream(resultByteArray).use { + it.copyTo(jarOutput!!) + } + jarOutput!!.closeEntry() + jarOutput!!.close() + } +} \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteCodeInjector.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/route/AssembleRouteModuleCodeInjector.kt similarity index 54% rename from GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteCodeInjector.kt rename to GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/route/AssembleRouteModuleCodeInjector.kt index e706a9a..cb5c837 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteCodeInjector.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/route/AssembleRouteModuleCodeInjector.kt @@ -1,10 +1,10 @@ -package com.wyjson.router.gradle_plugin.core +package com.wyjson.router.gradle_plugin.core.route import com.wyjson.router.gradle_plugin.utils.Constants -import com.wyjson.router.gradle_plugin.utils.Constants.INJECT_CLASS_NAME -import com.wyjson.router.gradle_plugin.utils.Constants.INJECT_METHOD_NAME -import com.wyjson.router.gradle_plugin.utils.Constants.INJECT_TARGET_METHOD_NAME -import com.wyjson.router.gradle_plugin.utils.Constants.SCAN_TARGET_INJECT_PACKAGE_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.ROUTE_MODULE_INJECT_CLASS_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.ROUTE_MODULE_INJECT_METHOD_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.ROUTE_MODULE_INJECT_TARGET_METHOD_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.ROUTE_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME import com.wyjson.router.gradle_plugin.utils.Constants._CLASS import com.wyjson.router.gradle_plugin.utils.Logger import org.objectweb.asm.ClassReader @@ -15,18 +15,20 @@ import org.objectweb.asm.Opcodes import org.objectweb.asm.commons.AdviceAdapter import java.io.InputStream -class AssembleModuleRouteCodeInjector(val moduleRouteClassList: List) { +class AssembleRouteModuleCodeInjector(val routeModuleClassList: List) { + + private val TAG = "RM" fun execute(inputStream: InputStream): ByteArray { - Logger.i("Start execute ASM method") + Logger.i(TAG, "Start execute ASM method") val classReader = ClassReader(inputStream) val classWriter = ClassWriter(ClassWriter.COMPUTE_MAXS) - val classVisitor = AssembleModuleRouteClassVisitor(classWriter) + val classVisitor = AssembleRouteModuleClassVisitor(classWriter) classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES) return classWriter.toByteArray() } - inner class AssembleModuleRouteClassVisitor(private val mClassVisitor: ClassVisitor) + inner class AssembleRouteModuleClassVisitor(private val mClassVisitor: ClassVisitor) : ClassVisitor(Opcodes.ASM9, mClassVisitor) { override fun visitMethod( @@ -37,32 +39,32 @@ class AssembleModuleRouteCodeInjector(val moduleRouteClassList: List) { exception: Array? ): MethodVisitor { var mv = mClassVisitor.visitMethod(access, name, desc, signature, exception) - if (INJECT_METHOD_NAME == name) { - mv = AssembleModuleRouteMethodAdapter(mv, access, name, desc) + if (ROUTE_MODULE_INJECT_METHOD_NAME == name) { + mv = AssembleRouteModuleMethodAdapter(mv, access, name, desc) } return mv } } - inner class AssembleModuleRouteMethodAdapter(mv: MethodVisitor, access: Int, name: String, desc: String?) + inner class AssembleRouteModuleMethodAdapter(mv: MethodVisitor, access: Int, name: String, desc: String?) : AdviceAdapter(Opcodes.ASM9, mv, access, name, desc) { override fun visitInsn(opcode: Int) { if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) { - if (moduleRouteClassList.isNotEmpty()) { - val injectClassName = INJECT_CLASS_NAME - Logger.i("Start inject the [${injectClassName}.${INJECT_METHOD_NAME}]") + if (routeModuleClassList.isNotEmpty()) { + val injectClassName = ROUTE_MODULE_INJECT_CLASS_NAME + Logger.i(TAG, "Start inject the [${injectClassName}.${ROUTE_MODULE_INJECT_METHOD_NAME}]") } else { - Logger.w("No need for an inject!") + Logger.w(TAG, "No need for an inject!") } - moduleRouteClassList.forEach { moduleRouterClassName -> - val name = Constants.slashToDot(SCAN_TARGET_INJECT_PACKAGE_NAME) + "." + moduleRouterClassName.replace(_CLASS, "") - Logger.i("inject the [${INJECT_TARGET_METHOD_NAME}(\"${name}\")]") + routeModuleClassList.forEach { routeModuleClassName -> + val name = Constants.slashToDot(ROUTE_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME) + "." + routeModuleClassName.replace(_CLASS, "") + Logger.i(TAG, "inject the [${ROUTE_MODULE_INJECT_TARGET_METHOD_NAME}(\"${name}\")]") mv.visitLdcInsn(name) mv.visitMethodInsn( INVOKESTATIC, - Constants.dotToSlash(INJECT_CLASS_NAME), - INJECT_TARGET_METHOD_NAME, + Constants.dotToSlash(ROUTE_MODULE_INJECT_CLASS_NAME), + ROUTE_MODULE_INJECT_TARGET_METHOD_NAME, "(Ljava/lang/String;)V", false ) @@ -77,7 +79,7 @@ class AssembleModuleRouteCodeInjector(val moduleRouteClassList: List) { override fun onMethodExit(opcode: Int) { super.onMethodExit(opcode) - Logger.i("End of method inject") + Logger.i(TAG, "End of method inject") } } } \ No newline at end of file diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteTask.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/route/AssembleRouteModuleTask.kt similarity index 70% rename from GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteTask.kt rename to GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/route/AssembleRouteModuleTask.kt index 550a402..73c6fb6 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/AssembleModuleRouteTask.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/core/route/AssembleRouteModuleTask.kt @@ -1,9 +1,9 @@ -package com.wyjson.router.gradle_plugin.core +package com.wyjson.router.gradle_plugin.core.route import com.wyjson.router.gradle_plugin.utils.Constants -import com.wyjson.router.gradle_plugin.utils.Constants.INJECT_CLASS_NAME -import com.wyjson.router.gradle_plugin.utils.Constants.MODULE_ROUTE_NAME_SUFFIX -import com.wyjson.router.gradle_plugin.utils.Constants.SCAN_TARGET_INJECT_PACKAGE_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.ROUTE_MODULE_INJECT_CLASS_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.ROUTE_MODULE_NAME_SUFFIX +import com.wyjson.router.gradle_plugin.utils.Constants.ROUTE_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME import com.wyjson.router.gradle_plugin.utils.Constants._CLASS import com.wyjson.router.gradle_plugin.utils.Logger import org.gradle.api.DefaultTask @@ -24,7 +24,9 @@ import java.util.jar.JarOutputStream import java.util.zip.ZipException import kotlin.system.measureTimeMillis -abstract class AssembleModuleRouteTask : DefaultTask() { +abstract class AssembleRouteModuleTask : DefaultTask() { + + private val TAG = "RM" @get:InputFiles abstract val allJars: ListProperty @@ -35,7 +37,7 @@ abstract class AssembleModuleRouteTask : DefaultTask() { @get:OutputFile abstract val output: RegularFileProperty - private val moduleRouteClassList = ArrayList() + private val routeModuleClassList = ArrayList() private var originInject: ByteArray? = null private var jarOutput: JarOutputStream? = null @@ -45,16 +47,16 @@ abstract class AssembleModuleRouteTask : DefaultTask() { val scanTimeCost = measureTimeMillis { scanFile() } - Logger.i("Scan finish, current cost time ${scanTimeCost}ms") + Logger.i(TAG, "Scan finish, current cost time ${scanTimeCost}ms") if (originInject == null) { - Logger.e("Can not find GoRouter inject point, Do you import [GoRouter-Api]???") + Logger.e(TAG, "Can not find GoRouter inject point, Do you import [GoRouter-Api]???") return } val injectCodeTimeCost = measureTimeMillis { injectCode() } - Logger.i("Inject code finish, current cost time ${injectCodeTimeCost}ms") + Logger.i(TAG, "Inject code finish, current cost time ${injectCodeTimeCost}ms") } private fun scanFile() { @@ -62,9 +64,9 @@ abstract class AssembleModuleRouteTask : DefaultTask() { // Logger.i("Scan to directory [${directory.asFile.absolutePath}]") directory.asFile.walk().forEach { file -> if (file.isFile) { - if (file.name.endsWith(MODULE_ROUTE_NAME_SUFFIX + _CLASS)) { - Logger.i("Scan to class [${file.name}] be from directory [${directory.asFile.absolutePath}]") - moduleRouteClassList.add(file.name) + if (file.name.endsWith(ROUTE_MODULE_NAME_SUFFIX + _CLASS)) { + Logger.i(TAG, "Scan to class [${file.name}] be from directory [${directory.asFile.absolutePath}]") + routeModuleClassList.add(file.name) } val relativePath = directory.asFile.toURI().relativize(file.toURI()).path // Logger.i("Scan the classes in the directory [${relativePath.replace(File.separatorChar, '.')}]") @@ -90,17 +92,17 @@ abstract class AssembleModuleRouteTask : DefaultTask() { if (jarEntry.isDirectory || jarEntry.name.isEmpty()) { continue } - if (Constants.dotToSlash(INJECT_CLASS_NAME) + _CLASS == entryName) { - Logger.i("Find the inject class [$entryName]") + if (Constants.dotToSlash(ROUTE_MODULE_INJECT_CLASS_NAME) + _CLASS == entryName) { + Logger.i(TAG, "Find the inject class [$entryName]") jarFile.getInputStream(jarEntry).use { inputs -> originInject = inputs.readAllBytes() } } else { - val startsWith = entryName.startsWith(Constants.dotToSlash(SCAN_TARGET_INJECT_PACKAGE_NAME)) - val endsWith = entryName.endsWith(Constants.dotToSlash(MODULE_ROUTE_NAME_SUFFIX) + _CLASS) + val startsWith = entryName.startsWith(Constants.dotToSlash(ROUTE_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME)) + val endsWith = entryName.endsWith(Constants.dotToSlash(ROUTE_MODULE_NAME_SUFFIX) + _CLASS) if (startsWith && endsWith) { val className = entryName.substring(entryName.lastIndexOf("/") + 1) - Logger.i("Scan to class [$className] be from jar [${file.asFile.absolutePath}]") + Logger.i(TAG, "Scan to class [$className] be from jar [${file.asFile.absolutePath}]") if (className.isNotEmpty()) { tempList.add(className) } @@ -113,18 +115,18 @@ abstract class AssembleModuleRouteTask : DefaultTask() { } } catch (e: Exception) { if (!(e is ZipException && e.message?.startsWith("duplicate entry:") == true)) { - Logger.w("Merge jar error entry:[${jarEntry.name}], error message:$e") + Logger.w(TAG, "Merge jar error entry:[${jarEntry.name}], error message:$e") } } } - moduleRouteClassList.addAll(tempList) + routeModuleClassList.addAll(tempList) jarFile.close() } } private fun injectCode() { - val resultByteArray = AssembleModuleRouteCodeInjector(moduleRouteClassList).execute(ByteArrayInputStream(originInject)) - jarOutput!!.putNextEntry(JarEntry(Constants.dotToSlash(INJECT_CLASS_NAME) + _CLASS)) + val resultByteArray = AssembleRouteModuleCodeInjector(routeModuleClassList).execute(ByteArrayInputStream(originInject)) + jarOutput!!.putNextEntry(JarEntry(Constants.dotToSlash(ROUTE_MODULE_INJECT_CLASS_NAME) + _CLASS)) ByteArrayInputStream(resultByteArray).use { it.copyTo(jarOutput!!) } diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt index 03d335d..9429eb1 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/doc/GenerateRouteDocTask.kt @@ -14,6 +14,8 @@ import java.io.File abstract class GenerateRouteDocTask : DefaultTask() { + private val TAG = "Doc" + init { group = Constants.PROJECT } @@ -24,7 +26,7 @@ abstract class GenerateRouteDocTask : DefaultTask() { @TaskAction fun taskAction() { - Logger.i("Generate GoRouter document task start.") + Logger.i(TAG, "Generate GoRouter document task start.") project.dependProject().forEach { curProject -> val genFile = curProject.file("${curProject.buildDir}/generated/ap_generated_sources/debug") @@ -32,26 +34,26 @@ abstract class GenerateRouteDocTask : DefaultTask() { val collection = curProject.files(genFile).asFileTree.filter { it.name.endsWith(Constants.DOCUMENT_FILE_NAME) } if (collection.isEmpty) { - Logger.w("project[${curProject.name}] scan 0 route document.") + Logger.w(TAG, "project[${curProject.name}] scan 0 route document.") } else { for (file in collection) { - Logger.i("project[${curProject.name}] found the file[${file.name}].") + Logger.i(TAG, "project[${curProject.name}] found the file[${file.name}].") mergeRouteModuleDoc(curProject, file) } } } if (document == null) { if (GENERATE_ROUTE_DOC_TASK_NAME == name) { - Logger.e("Failed to generate the route document!") + Logger.e(TAG, "Failed to generate the route document!") } else { - Logger.e("Failed to generate the route document! Use the '${GENERATE_ROUTE_DOC_TASK_NAME}' task to generate a new route document.") + Logger.e(TAG, "Failed to generate the route document! Use the '${GENERATE_ROUTE_DOC_TASK_NAME}' task to generate a new route document.") } return } val json = GsonBuilder().setPrettyPrinting().create().toJson(document) File(docOutFilePath).writeText(json, Charsets.UTF_8) - Logger.i("Generate GoRouter document task end.") - Logger.i("Success! route document name[${documentName}] $docOutFilePath") + Logger.i(TAG, "Generate GoRouter document task end.") + Logger.i(TAG, "Success! route document name[${documentName}] $docOutFilePath") } private fun mergeRouteModuleDoc(curProject: Project, file: File) { @@ -67,10 +69,10 @@ abstract class GenerateRouteDocTask : DefaultTask() { } document!!.interceptors.sortBy { interceptor -> interceptor.ordinal } } catch (e: Exception) { - Logger.e("module[${curProject.name}] route document parsing failed, do not modify the generated route file, use the '${GENERATE_ROUTE_DOC_TASK_NAME}' task to generate a new route document.") + Logger.e(TAG, "module[${curProject.name}] route document parsing failed, do not modify the generated route file, use the '${GENERATE_ROUTE_DOC_TASK_NAME}' task to generate a new route document.") } } else { - Logger.e("module[${curProject.name}] route document content is empty and a new route document is generated using the '${GENERATE_ROUTE_DOC_TASK_NAME}' task.") + Logger.e(TAG, "module[${curProject.name}] route document content is empty and a new route document is generated using the '${GENERATE_ROUTE_DOC_TASK_NAME}' task.") } } diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/launch/GradlePluginLaunch.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/launch/GradlePluginLaunch.kt index 18ce986..59ddb8d 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/launch/GradlePluginLaunch.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/launch/GradlePluginLaunch.kt @@ -6,9 +6,11 @@ import com.android.build.api.variant.ScopedArtifacts import com.android.build.gradle.AppPlugin import com.android.build.gradle.internal.tasks.factory.dependsOn import com.wyjson.router.gradle_plugin.config.GoRouterConfig -import com.wyjson.router.gradle_plugin.core.AssembleModuleRouteTask +import com.wyjson.router.gradle_plugin.core.application.AssembleApplicationModuleTask +import com.wyjson.router.gradle_plugin.core.route.AssembleRouteModuleTask import com.wyjson.router.gradle_plugin.doc.GenerateRouteDocTask -import com.wyjson.router.gradle_plugin.utils.Constants.ASSEMBLE_MODULE_ROUTE_TASK_TASK_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.ASSEMBLE_APPLICATION_MODULE_TASK_TASK_NAME +import com.wyjson.router.gradle_plugin.utils.Constants.ASSEMBLE_ROUTE_MODULE_TASK_TASK_NAME import com.wyjson.router.gradle_plugin.utils.Constants.GENERATE_ROUTE_DOC_TASK_NAME import com.wyjson.router.gradle_plugin.utils.Constants.QUICK_GENERATE_ROUTE_DOC_TASK_NAME import com.wyjson.router.gradle_plugin.utils.Logger @@ -17,14 +19,15 @@ import org.gradle.api.Project class GradlePluginLaunch : Plugin { + private val TAG = "Launch" + override fun apply(project: Project) { val isApp = project.plugins.hasPlugin(AppPlugin::class.java) if (!isApp) { - Logger.e("Plugin ['com.wyjson.Gorouter'] can only be used under the application, not under the module library invalid!") + Logger.e(TAG, "Plugin ['com.wyjson.Gorouter'] can only be used under the application, not under the module library invalid!") return } - project.tasks.register(GENERATE_ROUTE_DOC_TASK_NAME, GenerateRouteDocTask::class.java) - .dependsOn("build") + project.tasks.register(GENERATE_ROUTE_DOC_TASK_NAME, GenerateRouteDocTask::class.java).dependsOn("build") project.tasks.register(QUICK_GENERATE_ROUTE_DOC_TASK_NAME, GenerateRouteDocTask::class.java) project.extensions.add("GoRouter", GoRouterConfig::class.java) @@ -44,18 +47,26 @@ class GradlePluginLaunch : Plugin { isRunTask = true } if (isRunTask) { - val task = project.tasks.register( - "${variant.name}${ASSEMBLE_MODULE_ROUTE_TASK_TASK_NAME}", - AssembleModuleRouteTask::class.java - ) + val rmTask = project.tasks.register("${variant.name}${ASSEMBLE_ROUTE_MODULE_TASK_TASK_NAME}", AssembleRouteModuleTask::class.java) + variant.artifacts + .forScope(ScopedArtifacts.Scope.ALL) + .use(rmTask) + .toTransform( + ScopedArtifact.CLASSES, + AssembleRouteModuleTask::allJars, + AssembleRouteModuleTask::allDirectories, + AssembleRouteModuleTask::output + ) + + val amTask = project.tasks.register("${variant.name}${ASSEMBLE_APPLICATION_MODULE_TASK_TASK_NAME}", AssembleApplicationModuleTask::class.java) variant.artifacts .forScope(ScopedArtifacts.Scope.ALL) - .use(task) + .use(amTask) .toTransform( ScopedArtifact.CLASSES, - AssembleModuleRouteTask::allJars, - AssembleModuleRouteTask::allDirectories, - AssembleModuleRouteTask::output + AssembleApplicationModuleTask::allJars, + AssembleApplicationModuleTask::allDirectories, + AssembleApplicationModuleTask::output ) } } diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt index 3865be9..a6884ee 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Constants.kt @@ -3,7 +3,8 @@ package com.wyjson.router.gradle_plugin.utils object Constants { const val GENERATE_ROUTE_DOC_TASK_NAME = "generateRouteDoc"; const val QUICK_GENERATE_ROUTE_DOC_TASK_NAME = "quickGenerateRouteDoc"; - const val ASSEMBLE_MODULE_ROUTE_TASK_TASK_NAME = "AssembleModuleRouteTask"; + const val ASSEMBLE_ROUTE_MODULE_TASK_TASK_NAME = "AssembleRouteModuleTask"; + const val ASSEMBLE_APPLICATION_MODULE_TASK_TASK_NAME = "AssembleApplicationModuleTask"; private const val SEPARATOR = "$$"; private const val PACKAGE_NAME = "com.wyjson.router" @@ -13,19 +14,39 @@ object Constants { const val _CLASS = ".class" // 路由注册生成类名后缀$$Route - const val MODULE_ROUTE_NAME_SUFFIX = SEPARATOR + "Route" + const val ROUTE_MODULE_NAME_SUFFIX = SEPARATOR + "Route" // 需要扫描注入的类,所在的包名 - const val SCAN_TARGET_INJECT_PACKAGE_NAME = "$PACKAGE_NAME.module.route" + const val ROUTE_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME = "$PACKAGE_NAME.module.route" // 注入到这个类下 - const val INJECT_CLASS_NAME = "$PACKAGE_NAME.core.RouteModuleLoadCenter" + const val ROUTE_MODULE_INJECT_CLASS_NAME = "$PACKAGE_NAME.core.RouteModuleCenter" // 注入到这个方法 - const val INJECT_METHOD_NAME = "loadModuleRouteByPlugin" + const val ROUTE_MODULE_INJECT_METHOD_NAME = "loadByPlugin" // 注入内容方法名 - const val INJECT_TARGET_METHOD_NAME = "register" + const val ROUTE_MODULE_INJECT_TARGET_METHOD_NAME = "register" + + + /** + * application module + */ + + // application module生成的代理类名后缀$$AP + const val APPLICATION_MODULE_NAME_SUFFIX = SEPARATOR + "AP" + + // 需要扫描注入的类,所在的包名 + const val APPLICATION_MODULE_SCAN_TARGET_INJECT_PACKAGE_NAME = "$PACKAGE_NAME.module.application" + + // 注入到这个类下 + const val APPLICATION_MODULE_INJECT_CLASS_NAME = "$PACKAGE_NAME.core.ApplicationModuleCenter" + + // 注入到这个方法 + const val APPLICATION_MODULE_INJECT_METHOD_NAME = "loadByPlugin" + + // 注入内容方法名 + const val APPLICATION_MODULE_INJECT_TARGET_METHOD_NAME = "register" fun dotToSlash(str: String): String { diff --git a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Logger.kt b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Logger.kt index 6f06b83..20287f4 100644 --- a/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Logger.kt +++ b/GoRouter-Gradle-Plugin/src/main/kotlin/com/wyjson/router/gradle_plugin/utils/Logger.kt @@ -4,16 +4,16 @@ import com.wyjson.router.gradle_plugin.utils.Constants.PROJECT object Logger { - fun i(info: String) { - println("[info] ${PROJECT}::Gradle-Plugin >>> $info") + fun i(tag: String, info: String) { + println("[info] ${PROJECT}::Gradle-Plugin >>> TAG:$tag $info") } - fun w(info: String) { - println("[warning] ${PROJECT}::Gradle-Plugin >>> $info") + fun w(tag: String, info: String) { + println("[warning] ${PROJECT}::Gradle-Plugin >>> TAG:$tag $info") } - fun e(info: String) { - error("[error] ${PROJECT}::Gradle-Plugin >>> $info") + fun e(tag: String, info: String) { + error("[error] ${PROJECT}::Gradle-Plugin >>> TAG:$tag $info") } } \ No newline at end of file diff --git a/README.md b/README.md index f1e0445..907831b 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ public class TestActivity extend Activity { if (BuildConfig.DEBUG) { GoRouter.openDebug(); // 开启调试,查看路由详细加载和跳转过程日志 } -GoRouter.autoLoadModuleRoute(this); // 尽可能早,推荐在Application中初始化 +GoRouter.autoLoadRouteModule(this); // 尽可能早,推荐在Application中初始化 ``` ##### 5. 发起路由操作 @@ -133,7 +133,7 @@ GoRouter.getInstance().build("/test/fragment") .go(this); ``` -##### 6. 使用Gradle插件实现路由表的自动加载,支持Gradle7.4+ (可选) +##### 6. 使用Gradle插件实现路由表的自动加载,支持Gradle8.0+ (可选) ```groovy // 项目根目录下的settings.gradle @@ -164,7 +164,7 @@ plugins { id 'com.wyjson.gorouter' } ``` -* 支持Gradle7.4+,Gradle7.4以下参见5-7。 +* 支持Gradle8.0+,Gradle8.0以下参见5-7。 * 开发阶段构建加速参见5-8(最好在开发阶段开启,节省build时间)。 * 可选使用,通过GoRouter提供的注册插件进行路由表的自动加载,默认通过扫描dex的方式进行加载(在运行时注册,节省打包时间),通过gradle插件进行自动注册可以缩短运行时初始化时间(在打包时注册,节省运行时间),解决应用加固导致无法直接访问dex文件。 @@ -515,7 +515,7 @@ GoRouter.getInstance().build("/user/card/fragment").commitFragment(CardFragment. ##### 7. 自定义模块路由加载 -如不使用gradle插件[3-6]进行自动注册,也不想走默认扫描dex的方式,可以不调用`GoRouter.autoLoadModuleRoute(this);`方法,但需要自行调用模块生成的路由加载类。 +如不使用gradle插件[3-6]进行自动注册,也不想走默认扫描dex的方式,可以不调用`GoRouter.autoLoadRouteModule(this);`方法,但需要自行调用模块生成的路由加载类。 模块项目里至少使用一条注解`@Route`、`@Service`、`@Interceptor`,就会生成对应路由表的加载类。路由表加载类命名规则会根据`GOROUTER_MODULE_NAME `设置的模块名称转换成大写驼峰命名+`$$Route.java`,所有模块生成的路由表加载类都会放到`com.wyjson.router.module.route`包下。 例如模块名称`module_user`会生成`ModuleUser$$Route.java` diff --git a/app/src/main/java/com/wyjson/go_router/MyApplication.java b/app/src/main/java/com/wyjson/go_router/MyApplication.java index acccdcc..a0a7ca5 100644 --- a/app/src/main/java/com/wyjson/go_router/MyApplication.java +++ b/app/src/main/java/com/wyjson/go_router/MyApplication.java @@ -1,6 +1,9 @@ package com.wyjson.go_router; import android.app.Application; +import android.content.res.Configuration; + +import androidx.annotation.NonNull; import com.wyjson.module_common.BuildConfig; import com.wyjson.router.GoRouter; @@ -12,8 +15,40 @@ public void onCreate() { super.onCreate(); if (BuildConfig.DEBUG) { GoRouter.openDebug(); -// GoRouter.printStackTrace(); } - GoRouter.autoLoadModuleRoute(this); + // 自动加载所有路由模块的路由 + GoRouter.autoLoadRouteModule(this); + + // 这部分是多模块application,如不使用多模块application可以不调用这两句 + GoRouter.autoLoadAM(this); + GoRouter.executeAMOnCreate(this); + } + + @Override + public void onTerminate() { + super.onTerminate(); + // 这部分是多模块application,如不使用多模块application可以不调用 + GoRouter.executeAMOnTerminate(); + } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + // 这部分是多模块application,如不使用多模块application可以不调用 + GoRouter.executeAMOnConfigurationChanged(newConfig); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + // 这部分是多模块application,如不使用多模块application可以不调用 + GoRouter.executeAMOnLowMemory(); + } + + @Override + public void onTrimMemory(int level) { + super.onTrimMemory(level); + // 这部分是多模块application,如不使用多模块application可以不调用 + GoRouter.executeAMOnTrimMemory(level); } } diff --git a/gradle.properties b/gradle.properties index a845fcd..9b72605 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +#org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects @@ -21,8 +21,8 @@ android.useAndroidX=true android.nonTransitiveRClass=true # Debug APT -# org.gradle.daemon=true -# org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 + org.gradle.daemon=true + org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 GROUP_ID=com.github.wyjsonGo.GoRouter VERSION=1.2.0 \ No newline at end of file diff --git a/module_common/src/main/java/com/wyjson/module_common/CommonApplication.java b/module_common/src/main/java/com/wyjson/module_common/CommonApplication.java new file mode 100644 index 0000000..aa58f1f --- /dev/null +++ b/module_common/src/main/java/com/wyjson/module_common/CommonApplication.java @@ -0,0 +1,27 @@ +package com.wyjson.module_common; + +import android.app.Application; +import android.util.Log; + +import com.wyjson.router.annotation.ApplicationModule; +import com.wyjson.router.interfaces.IApplicationModule; + +@ApplicationModule +public class CommonApplication implements IApplicationModule { + + @Override + public int setPriority() { + return PRIORITY_MAX; + } + + @Override + public void onCreate(Application app) { + Log.d("CommonApplication", "onCreate()"); + } + + @Override + public void onLoadAsync(Application app) { + Log.d("CommonApplication", "loadAsync()"); + } + +} diff --git a/module_main/src/main/java/com/wyjson/module_main/MainApplication.java b/module_main/src/main/java/com/wyjson/module_main/MainApplication.java new file mode 100644 index 0000000..538252d --- /dev/null +++ b/module_main/src/main/java/com/wyjson/module_main/MainApplication.java @@ -0,0 +1,21 @@ +package com.wyjson.module_main; + +import android.app.Application; +import android.util.Log; + +import com.wyjson.router.annotation.ApplicationModule; +import com.wyjson.router.interfaces.IApplicationModule; + +@ApplicationModule +public class MainApplication implements IApplicationModule { + + @Override + public void onCreate(Application app) { + Log.d("MainApplication", "onCreate()"); + } + + @Override + public void onLoadAsync(Application app) { + Log.d("MainApplication", "loadAsync()"); + } +} diff --git a/module_user/src/main/java/com/wyjson/module_user/UserApplication.java b/module_user/src/main/java/com/wyjson/module_user/UserApplication.java new file mode 100644 index 0000000..1eadbd3 --- /dev/null +++ b/module_user/src/main/java/com/wyjson/module_user/UserApplication.java @@ -0,0 +1,21 @@ +package com.wyjson.module_user; + +import android.app.Application; +import android.util.Log; + +import com.wyjson.router.annotation.ApplicationModule; +import com.wyjson.router.interfaces.IApplicationModule; + +@ApplicationModule +public class UserApplication implements IApplicationModule { + + @Override + public void onCreate(Application app) { + Log.d("UserApplication", "onCreate()"); + } + + @Override + public void onLoadAsync(Application app) { + Log.d("UserApplication", "loadAsync()"); + } +} From 1e4323500e8fb203b01e9392118b5ffb9bde02c5 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Sun, 12 Nov 2023 23:26:13 +0800 Subject: [PATCH 24/28] update README.md --- .../main/java/com/wyjson/router/GoRouter.java | 20 +++--- .../router/core/ApplicationModuleCenter.java | 26 ++++---- .../router/interfaces/IApplicationModule.java | 2 +- README.md | 61 ++++++++++++++++--- .../com/wyjson/go_router/MyApplication.java | 10 +-- .../module_common/CommonApplication.java | 40 +++++++++++- .../wyjson/module_main/MainApplication.java | 3 +- .../wyjson/module_user/UserApplication.java | 6 +- 8 files changed, 129 insertions(+), 39 deletions(-) diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java index 55f96aa..bbb7b1b 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java @@ -120,24 +120,24 @@ public boolean isAMRegisterMode() { return ApplicationModuleCenter.isRegisterByPlugin(); } - public static void executeAMOnCreate(Application app) { - ApplicationModuleCenter.executeOnCreate(app); + public static void callAMOnCreate(Application app) { + ApplicationModuleCenter.callOnCreate(app); } - public static void executeAMOnTerminate() { - ApplicationModuleCenter.executeOnTerminate(); + public static void callAMOnTerminate() { + ApplicationModuleCenter.callOnTerminate(); } - public static void executeAMOnConfigurationChanged(@NonNull Configuration newConfig) { - ApplicationModuleCenter.executeOnConfigurationChanged(newConfig); + public static void callAMOnConfigurationChanged(@NonNull Configuration newConfig) { + ApplicationModuleCenter.callOnConfigurationChanged(newConfig); } - public static void executeAMOnLowMemory() { - ApplicationModuleCenter.executeOnLowMemory(); + public static void callAMOnLowMemory() { + ApplicationModuleCenter.callOnLowMemory(); } - public static void executeAMOnTrimMemory(int level) { - ApplicationModuleCenter.executeOnTrimMemory(level); + public static void callAMOnTrimMemory(int level) { + ApplicationModuleCenter.callOnTrimMemory(level); } /** diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/core/ApplicationModuleCenter.java b/GoRouter-Api/src/main/java/com/wyjson/router/core/ApplicationModuleCenter.java index 47cd7cb..1f35d77 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/core/ApplicationModuleCenter.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/core/ApplicationModuleCenter.java @@ -175,10 +175,10 @@ public int compare(IApplicationModule o1, IApplicationModule o2) { } private interface Consumer { - void execute(IApplicationModule ma); + void call(IApplicationModule ma); } - private static void execute(Consumer consumer) { + private static void call(Consumer consumer) { if (Warehouse.applicationModules.isEmpty()) { return; } @@ -187,13 +187,13 @@ private static void execute(Consumer consumer) { listComparator = null; } for (IApplicationModule am : Warehouse.applicationModules) { - consumer.execute(am); + consumer.call(am); } } - public static void executeOnCreate(Application app) { + public static void callOnCreate(Application app) { load(app); - execute(am -> { + call(am -> { am.onCreate(app); new Thread(() -> { // 设置线程的优先级,不与主线程抢资源 @@ -203,19 +203,19 @@ public static void executeOnCreate(Application app) { }); } - public static void executeOnTerminate() { - execute(IApplicationModule::onTerminate); + public static void callOnTerminate() { + call(IApplicationModule::onTerminate); } - public static void executeOnConfigurationChanged(@NonNull Configuration newConfig) { - execute(ma -> ma.onConfigurationChanged(newConfig)); + public static void callOnConfigurationChanged(@NonNull Configuration newConfig) { + call(ma -> ma.onConfigurationChanged(newConfig)); } - public static void executeOnLowMemory() { - execute(IApplicationModule::onLowMemory); + public static void callOnLowMemory() { + call(IApplicationModule::onLowMemory); } - public static void executeOnTrimMemory(int level) { - execute(ma -> ma.onTrimMemory(level)); + public static void callOnTrimMemory(int level) { + call(ma -> ma.onTrimMemory(level)); } } diff --git a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IApplicationModule.java b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IApplicationModule.java index 441a676..055e39f 100644 --- a/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IApplicationModule.java +++ b/GoRouter-Api/src/main/java/com/wyjson/router/interfaces/IApplicationModule.java @@ -13,7 +13,7 @@ public interface IApplicationModule { /** * The priority of the module application, - * which will execute them in order from largest to smallest execution. + * which will be executed in order from largest to smallest. */ default int setPriority() { return PRIORITY_NORM; diff --git a/README.md b/README.md index 907831b..fee5f2d 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,14 @@ | 功能 | ARouter | GoRouter | 描述 | | ---------------------- | -------- | --------- | ---------------------------------------------------- | | 路由注册方式 | 注解 | 注解、java | GoRouter不仅提供了注解,还能使用java方式注册,参见5-6 | -| 服务 | 一对多 | 一对一 | ARouter可以为一个服务接口注册多个实现类(没啥用),本库一个服务接口对应一个实现方法(调用更方便) | -| 动态注册拦截器 | 不支持 | 支持 | ARouter只能动态注册路由,不能动态注册拦截器 | +| 服务 | 一对多 | 一对一 | ARouter可以为一个服务接口注册多个实现类(没啥用),本库一个服务接口对应一个实现方法(调用更方便) | +| 动态注册拦截器 | 不支持 | 支持 | ARouter只能动态注册路由,不能动态注册拦截器 | | 重写跳转URL服务 | 支持 | 不支持 | 可以在`PretreatmentService`里实现相同功能 | -| 获取元数据 | 不支持 | 支持 | 有些场景需要判断某个页面当前是否存在等需求,就需要获取页面class等信息,参见5-1 | +| 获取元数据 | 不支持 | 支持 | 有些场景需要判断某个页面当前是否存在等需求,就需要获取页面class等信息,参见5-1 | | withObject() | 支持 | 不支持 | ARouter实现原理是转JSON后使用`withString()`方法传递 | | inject(T) | 单一 | 更多 | ARouter不能在`onNewIntent()`方法里使用,GoRouter提供了更多使用场景 | | 按组分类、按需初始化 | 支持 | 支持 | ARouter不允许多个module中存在相同的分组,GoRouter允许 | -| 多模块Application生命周期 | 不支持 | 待开发 | 模块化路由都有了,肯定也需要多模块Application生命周期,正好本库Api、注解处理器、自动注册都有,所以开发一下这个功能很方便 | +| 模块Application生命周期 | 不支持 | 支持 | 主动分发到业务模块,让模块无侵入的获取Application生命周期,参见6-1 | *** @@ -41,7 +41,7 @@ 13. **支持生成路由文档** 14. 支持增量编译 15. 支持动态注册路由、路由组、服务和拦截器 -16. 支持多模块Application生命周期(待开发) +16. 支持模块Application生命周期 ## 二、典型应用 @@ -49,7 +49,7 @@ 2. 跨模块页面跳转,模块间解耦 3. 拦截跳转过程,处理登陆、埋点等逻辑 4. 跨模块API调用,通过控制反转来做组件解耦 -5. 多模块Application生命周期(待开发) +5. 多模块Application生命周期 ## 三、基础功能 @@ -561,7 +561,54 @@ GoRouter { 生成的路由文档会保存到项目下的`/app/项目名-route-doc.json`,Demo示例[/app/GoRouter-route-doc.json](https://github.com/wyjsonGo/GoRouter/blob/master/app/GoRouter-route-doc.json) -## 六、其他 +## 六、模块Application生命周期 + +Application生命周期主动分发到组件,让模块无侵入的获得Application生命周期 + +##### 1. 在模块中添加`@ApplicationModule`注解,实现`IApplicationModule`接口 + +```java +@ApplicationModule +public class UserApplication implements IApplicationModule { + + @Override + public void onCreate(Application app) { + // do something. + } + + /** + * 优化启动速度,一些不着急的初始化可以放在这里做,子线程 + */ + @Override + public void onLoadAsync(Application app) { + // do something. + } +} +``` + +Demo示例[CommonApplication.java](https://github.com/wyjsonGo/GoRouter/blob/master/module_common/src/main/java/com/wyjson/module_common/CommonApplication.java) + +##### 2. 在主Application添加分发 + +```java +public class MyApplication extends Application { + + @Override + public void onCreate() { + super.onCreate(); + // 调用callAMOnCreate()方法,触发模块Application的onCreate()、onLoadAsync()方法。 + GoRouter.callAMOnCreate(this); + } +``` + +Demo示例[MyApplication.java](https://github.com/wyjsonGo/GoRouter/blob/master/app/src/main/java/com/wyjson/go_router/MyApplication.java) + +##### 3. 进阶用法 + +* 指定模块Application优先级,可以重写`setPriority()`方法,它将按照从大到小的执行顺序执行。 +* `IApplicationModule`接口不紧提供了`onCreate`、`onLoadAsync`方法,还提供了`onTerminate`、`onConfigurationChanged`、`onLowMemory`、`onTrimMemory`方法,如需监听记得在主Application中添加他们的分发方法`GoRouter.callAMOnCreate()`、`GoRouter.callAMOnTerminate()`、`GoRouter.callAMOnConfigurationChanged(newConfig)`、`GoRouter.callAMOnLowMemory()`、`GoRouter.callAMOnTrimMemory(level)`。 + +## 七、其他 ##### 1. 路由中的分组概念 diff --git a/app/src/main/java/com/wyjson/go_router/MyApplication.java b/app/src/main/java/com/wyjson/go_router/MyApplication.java index 008947b..79212a9 100644 --- a/app/src/main/java/com/wyjson/go_router/MyApplication.java +++ b/app/src/main/java/com/wyjson/go_router/MyApplication.java @@ -17,7 +17,7 @@ public void onCreate() { GoRouter.openDebug(); } // 这部分是多模块application,如不使用多模块application可以不调用 - GoRouter.executeAMOnCreate(this); + GoRouter.callAMOnCreate(this); // 自动加载所有路由模块的路由 GoRouter.autoLoadRouteModule(this); @@ -27,27 +27,27 @@ public void onCreate() { public void onTerminate() { super.onTerminate(); // 这部分是多模块application,如不使用多模块application可以不调用 - GoRouter.executeAMOnTerminate(); + GoRouter.callAMOnTerminate(); } @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); // 这部分是多模块application,如不使用多模块application可以不调用 - GoRouter.executeAMOnConfigurationChanged(newConfig); + GoRouter.callAMOnConfigurationChanged(newConfig); } @Override public void onLowMemory() { super.onLowMemory(); // 这部分是多模块application,如不使用多模块application可以不调用 - GoRouter.executeAMOnLowMemory(); + GoRouter.callAMOnLowMemory(); } @Override public void onTrimMemory(int level) { super.onTrimMemory(level); // 这部分是多模块application,如不使用多模块application可以不调用 - GoRouter.executeAMOnTrimMemory(level); + GoRouter.callAMOnTrimMemory(level); } } diff --git a/module_common/src/main/java/com/wyjson/module_common/CommonApplication.java b/module_common/src/main/java/com/wyjson/module_common/CommonApplication.java index aa58f1f..3da50fe 100644 --- a/module_common/src/main/java/com/wyjson/module_common/CommonApplication.java +++ b/module_common/src/main/java/com/wyjson/module_common/CommonApplication.java @@ -1,14 +1,22 @@ package com.wyjson.module_common; import android.app.Application; +import android.content.res.Configuration; import android.util.Log; +import androidx.annotation.NonNull; + import com.wyjson.router.annotation.ApplicationModule; import com.wyjson.router.interfaces.IApplicationModule; @ApplicationModule public class CommonApplication implements IApplicationModule { + /** + * 模块应用程序的优先级,它将按照从大到小的执行顺序执行。 + * + * @return + */ @Override public int setPriority() { return PRIORITY_MAX; @@ -19,9 +27,39 @@ public void onCreate(Application app) { Log.d("CommonApplication", "onCreate()"); } + /** + * 优化启动速度,一些不着急的初始化可以放在这里做,子线程 + * + * @param app + */ @Override public void onLoadAsync(Application app) { - Log.d("CommonApplication", "loadAsync()"); + Log.d("CommonApplication", "onLoadAsync()"); + } + + + /** + * 以下方法可以不实现,按需添加 + */ + + @Override + public void onTerminate() { + Log.d("CommonApplication", "onTerminate()"); + } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + Log.d("CommonApplication", "onConfigurationChanged()"); + } + + @Override + public void onLowMemory() { + Log.d("CommonApplication", "onLowMemory()"); + } + + @Override + public void onTrimMemory(int level) { + Log.d("CommonApplication", "onTrimMemory() level:" + level); } } diff --git a/module_main/src/main/java/com/wyjson/module_main/MainApplication.java b/module_main/src/main/java/com/wyjson/module_main/MainApplication.java index 538252d..34dfd62 100644 --- a/module_main/src/main/java/com/wyjson/module_main/MainApplication.java +++ b/module_main/src/main/java/com/wyjson/module_main/MainApplication.java @@ -16,6 +16,7 @@ public void onCreate(Application app) { @Override public void onLoadAsync(Application app) { - Log.d("MainApplication", "loadAsync()"); + Log.d("MainApplication", "onLoadAsync()"); } + } diff --git a/module_user/src/main/java/com/wyjson/module_user/UserApplication.java b/module_user/src/main/java/com/wyjson/module_user/UserApplication.java index 1eadbd3..9377e20 100644 --- a/module_user/src/main/java/com/wyjson/module_user/UserApplication.java +++ b/module_user/src/main/java/com/wyjson/module_user/UserApplication.java @@ -1,8 +1,11 @@ package com.wyjson.module_user; import android.app.Application; +import android.content.res.Configuration; import android.util.Log; +import androidx.annotation.NonNull; + import com.wyjson.router.annotation.ApplicationModule; import com.wyjson.router.interfaces.IApplicationModule; @@ -16,6 +19,7 @@ public void onCreate(Application app) { @Override public void onLoadAsync(Application app) { - Log.d("UserApplication", "loadAsync()"); + Log.d("UserApplication", "onLoadAsync()"); } + } From a227b7c181305c529c6ce7a133817eb7bfeb799d Mon Sep 17 00:00:00 2001 From: Wyjson Date: Mon, 13 Nov 2023 10:25:10 +0800 Subject: [PATCH 25/28] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6ea030e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Wyjson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 07c5acbfd25ea1523c98cc56868cbb89e4481c9c Mon Sep 17 00:00:00 2001 From: Wyjson Date: Mon, 13 Nov 2023 10:28:36 +0800 Subject: [PATCH 26/28] update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fee5f2d..32d3a78 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [GoRouter](https://github.com/wyjsonGo/GoRouter) -[![License](https://img.shields.io/badge/license-Apache%202-green.svg)](https://www.apache.org/licenses/LICENSE-2.0) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/wyjsonGo/GoRouter/blob/main/LICENSE) > 一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦 From 9871ab351a84d41ca1759c9291c9e1f2b7023378 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Mon, 13 Nov 2023 10:28:36 +0800 Subject: [PATCH 27/28] update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fee5f2d..d4a5709 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # [GoRouter](https://github.com/wyjsonGo/GoRouter) -[![License](https://img.shields.io/badge/license-Apache%202-green.svg)](https://www.apache.org/licenses/LICENSE-2.0) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/wyjsonGo/GoRouter/blob/main/LICENSE) +[![Release Version](https://jitpack.io/v/wyjsonGo/GoRouter.svg)](https://jitpack.io/#wyjsonGo/GoRouter) > 一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦 From 0466d273c836fe33de4199c31e1d3d0537c48d84 Mon Sep 17 00:00:00 2001 From: Wyjson Date: Mon, 13 Nov 2023 10:38:08 +0800 Subject: [PATCH 28/28] publish v2.0.0 --- app/build.gradle | 10 +++++----- build.gradle | 2 +- gradle.properties | 2 +- settings.gradle | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 78e8686..dd43851 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,11 +1,11 @@ plugins { id 'com.android.application' - id 'com.wyjson.gorouter' -} -GoRouter { - // 允许执行自动注册任务的集合,最好不要写debug,以节省开发阶段build时间。 - buildTypes "release" +// id 'com.wyjson.gorouter' } +//GoRouter { +// // 允许执行自动注册任务的集合,最好不要写debug,以节省开发阶段build时间。 +// buildTypes "release" +//} android { namespace 'com.wyjson.go_router' compileSdk 33 diff --git a/build.gradle b/build.gradle index e98bfee..01f2b31 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { dependencies { - classpath "com.github.wyjsonGo.GoRouter:GoRouter-Gradle-Plugin:${VERSION}" +// classpath "com.github.wyjsonGo.GoRouter:GoRouter-Gradle-Plugin:${VERSION}" } } diff --git a/gradle.properties b/gradle.properties index a845fcd..2279c3e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -25,4 +25,4 @@ android.nonTransitiveRClass=true # org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 GROUP_ID=com.github.wyjsonGo.GoRouter -VERSION=1.2.0 \ No newline at end of file +VERSION=2.0.0 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index f9fa1c6..78af213 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,6 @@ pluginManagement { repositories { - mavenLocal() +// mavenLocal() maven { url 'https://jitpack.io' } google() mavenCentral()