使用
build.gradle
1 implementation 'com.google.auto.service:auto-service:1.0 -rc7'
ITest.java
1 2 3 public interface ITest { void print(); }
Test.java
1 2 3 4 5 6 7 8 @AutoService(ITest.class) public class Test implements ITest { @Override public void print() { Log.d("song" , "hahaha" ); } }
调用
1 ServiceLoader.load(ITest.class).iterator().next().print();
输出
apk/META-INF
原理
ServiceLoader 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 public final class ServiceLoader <S > implements Iterable <S > { private static final String PREFIX = "META-INF/services/" ; public static <S> ServiceLoader<S> load (Class<S> service, ClassLoader loader) { return new ServiceLoader<>(service, loader); } public void reload () { providers.clear(); lookupIterator = new LazyIterator(service, loader); } private ServiceLoader (Class<S> svc, ClassLoader cl) { service = Objects.requireNonNull(svc, "Service interface cannot be null" ); loader = (cl == null ) ? ClassLoader.getSystemClassLoader() : cl; reload(); } private class LazyIterator implements Iterator <S > { private boolean hasNextService () { if (nextName != null ) { return true ; } if (configs == null ) { try { String fullName = PREFIX + service.getName(); if (loader == null ) configs = ClassLoader.getSystemResources(fullName); else configs = loader.getResources(fullName); } catch (IOException x) { fail(service, "Error locating configuration files" , x); } } while ((pending == null ) || !pending.hasNext()) { if (!configs.hasMoreElements()) { return false ; } pending = parse(service, configs.nextElement()); } nextName = pending.next(); return true ; } } private Iterator<String> parse (Class<?> service, URL u) throws ServiceConfigurationError { InputStream in = null ; BufferedReader r = null ; ArrayList<String> names = new ArrayList<>(); try { in = u.openStream(); r = new BufferedReader(new InputStreamReader(in, "utf-8" )); int lc = 1 ; while ((lc = parseLine(service, u, r, lc, names)) >= 0 ); } catch (IOException x) { fail(service, "Error reading configuration file" , x); } finally { try { if (r != null ) r.close(); if (in != null ) in.close(); } catch (IOException y) { fail(service, "Error closing configuration file" , y); } } return names.iterator(); } }
通过ClassLoader的_getSystemResources或者_getResources获取META-INF/services/com.leo.events.cardcontrol.ITest文件,然后在通过parse方法进行解析ITest文件内容,然后再通过解析出的com.leo.events.cardcontrol.Test内容进行反射初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private S nextService () { if (!hasNextService()) throw new NoSuchElementException(); String cn = nextName; nextName = null ; Class<?> c = null ; try { c = Class.forName(cn, false , loader); } catch (ClassNotFoundException x) { } if (!service.isAssignableFrom(c)) { ClassCastException cce = new ClassCastException( service.getCanonicalName() + " is not assignable from " + c.getCanonicalName()); } try { S p = service.cast(c.newInstance()); providers.put(cn, p); return p; } catch (Throwable x) { fail(service, "Provider " + cn + " could not be instantiated" , x); } throw new Error(); }
AutoService 1 2 3 4 5 6 7 8 9 10 11 12 13 |------------------------------------------------------------------------ | javaPreCompileDebug , poseidon| |------------------------------------------------------------------------ | com.android.build.gradle.tasks.JavaPreCompileTask_Decorated |------------------------------------------------------------------------ | inputs file| |----------------------------------------------------------------- | 没有inputs路径 |----------------------------------------------------------------- | outputs file| |----------------------------------------------------------------- | /Users/juneleo/demo/CardControl/poseidon/build/intermediates/annotation_processor_list/debug/annotationProcessors.json |-----------------------------------------------------------------
在compileDebugJavaWithJavac之前执行javaPreCompileDebug,这个任务会输出annotationProcessors.json
1 2 3 4 5 6 { "bundle_apt-1.1.3.jar (com.autonavi.scm:bundle_apt:1.1.3)" : false , "aui-annotation-0.0.7.jar (com.autonavi.aui-annotation:aui-annotation:0.0.7)" : false , "hostkeep.jar (project :hostkeep)" : false , "auto-service-1.0-rc7.jar (com.google.auto.service:auto-service:1.0-rc7)" : true }
在这个json中指定了使用annotationProcessor依赖的项目
JavaPreCompileTask
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 abstract class JavaPreCompileWorkAction : ProfileAwareWorkAction <JavaPreCompileParameters > () { override fun run () { val annotationProcessors = detectAnnotationProcessors( parameters.annotationProcessorClassNames.get (), parameters.annotationProcessorArtifacts.get () ) writeAnnotationProcessorsToJsonFile( annotationProcessors, parameters.annotationProcessorListFile.get ().asFile ) } } const val ANNOTATION_PROCESSORS_INDICATOR_FILE = "META-INF/services/javax.annotation.processing.Processor" const val INCREMENTAL_ANNOTATION_PROCESSORS_INDICATOR_FILE = "META-INF/gradle/incremental.annotation.processors" fun detectAnnotationProcessors ( artifacts: Collection <SerializableArtifact > ) : Map<SerializableArtifact, Boolean > { val processors = mutableMapOf<SerializableArtifact, Boolean >() for (artifact in artifacts) { val artifactFile = artifact.file if (artifactFile.isDirectory) { if (File(artifactFile, ANNOTATION_PROCESSORS_INDICATOR_FILE).exists()) { processors[artifact] = File(artifactFile, INCREMENTAL_ANNOTATION_PROCESSORS_INDICATOR_FILE) .exists() } } else if (artifactFile.isFile) { try { JarFile(artifactFile).use { jarFile -> if (jarFile.getJarEntry(ANNOTATION_PROCESSORS_INDICATOR_FILE) != null ) { processors[artifact] = jarFile.getJarEntry( INCREMENTAL_ANNOTATION_PROCESSORS_INDICATOR_FILE ) != null } } } catch (e: IOException) { } } } return processors }
META-INF/services/javax.annotation.processing.Processor文件
输出路径
JavaCompile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |------------------------------------------------------------------------ | compileDebugJavaWithJavac , app| |------------------------------------------------------------------------ | org.gradle.api.tasks.compile.JavaCompile_Decorated |------------------------------------------------------------------------ | inputs file| |----------------------------------------------------------------- | /Users/juneleo/demo/CardControl/app/build/intermediates/annotation_processor_list/debug/annotationProcessors.json | |----------------------------------------------------------------- | outputs file| |----------------------------------------------------------------- | /Users/juneleo/demo/CardControl/app/build/generated/ap_generated_sources/debug/out | /Users/juneleo/demo/CardControl/app/build/intermediates/javac/debug/classes |-----------------------------------------------------------------
从图中我们可以看到JavaPreCompileTask的输出作为了JavaCompile的输入
annotationprocess调用链
JavaCompile调用jdk入口
1 2 3 4 5 6 7 8 9 10 11 12 13 public Result doCall() { if (!this .used.getAndSet(true )) { this .initContext(); this .notYetEntered = new HashMap(); this .compilerMain.setAPIMode(true ); this .result = this .compilerMain.compile(this .args, this .classNames, this .context, this .fileObjects, this .processors); this .cleanup(); return this .result; } else { throw new IllegalStateException("multiple calls to method 'call'" ); } }
args参数
processor参数