files = FileUtils.listFiles(packageDir,
+ new SuffixFileFilter(SdkConstants.DOT_CLASS, IOCase.INSENSITIVE), TrueFileFilter.INSTANCE);
+ for (File f : files) {
+ String className = trimName(f.getAbsolutePath(), dir.getAbsolutePath().length() + 1)
+ .replace(File.separatorChar, '.');
+ initClasses.add(className);
+ ServiceLoaderLogger.info(" find ServiceInitClass: %s", className);
+ }
+ }
+ }
+
+ /**
+ * [prefix]com/xxx/aaa.class --> com/xxx/aaa
+ * [prefix]com\xxx\aaa.class --> com\xxx\aaa
+ */
+ private String trimName(String s, int start) {
+ return s.substring(start, s.length() - SdkConstants.DOT_CLASS.length());
+ }
+
+ /**
+ * 生成格式如下的代码,其中ServiceInit_xxx由注解生成器生成。
+ *
+ * package com.sankuai.waimai.router.generated;
+ *
+ * public class ServiceLoaderInit {
+ *
+ * public static void init() {
+ * ServiceInit_xxx1.init();
+ * ServiceInit_xxx2.init();
+ * }
+ * }
+ *
+ */
+ private void generateServiceInitClass(String directory, Set classes) {
+
+ if (classes.isEmpty()) {
+ ServiceLoaderLogger.info(GENERATE_INIT + "skipped, no service found");
+ return;
+ }
+
+ try {
+ ServiceLoaderLogger.info(GENERATE_INIT + "start...");
+ long ms = System.currentTimeMillis();
+
+ ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
+ ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, writer) {
+ };
+ String className = Const.SERVICE_LOADER_INIT.replace('.', '/');
+ cv.visit(50, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
+
+ MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
+ Const.INIT_METHOD, "()V", null, null);
+
+ mv.visitCode();
+
+ for (String clazz : classes) {
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, clazz.replace('.', '/'),
+ "init",
+ "()V",
+ false);
+ }
+ mv.visitMaxs(0, 0);
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitEnd();
+ cv.visitEnd();
+
+ File dest = new File(directory, className + SdkConstants.DOT_CLASS);
+ dest.getParentFile().mkdirs();
+ new FileOutputStream(dest).write(writer.toByteArray());
+
+ ServiceLoaderLogger.info(GENERATE_INIT + "cost %s ms", System.currentTimeMillis() - ms);
+
+ } catch (IOException e) {
+ ServiceLoaderLogger.fatal(e);
+ }
+ }
+}
diff --git a/plugin/src/main/resources/META-INF/gradle-plugins/ServiceLoader.properties b/plugin/src/main/resources/META-INF/gradle-plugins/ServiceLoader.properties
new file mode 100755
index 0000000..1248e63
--- /dev/null
+++ b/plugin/src/main/resources/META-INF/gradle-plugins/ServiceLoader.properties
@@ -0,0 +1 @@
+implementation-class=com.blued.android.module.plugin.ServiceLoaderPlugin
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..c1d1ef1
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':plugin'