1. public abstract class Transform {
    2. /**
    3. * 用于指明 Transform 的名字,也对应了该 Transform 所代表的 Task 名称
    4. */
    5. @NonNull
    6. public abstract String getName();
    7. /**
    8. * Whether this transform should be applied to a given variant.
    9. *
    10. * @since 3.4
    11. * @return true if the transform should be applied to a given variant, false otherwise.
    12. * @param variant information about the current variant.
    13. */
    14. @Incubating
    15. public boolean applyToVariant(@NonNull VariantInfo variant) {
    16. return true;
    17. }
    18. /**
    19. * 用于指明 Transform 的输入类型,可以作为输入过滤的手段
    20. *
    21. // 代表 javac 编译成的 class 文件,常用
    22. public static final Set<ContentType> CONTENT_CLASS;
    23. public static final Set<ContentType> CONTENT_JARS;
    24. // 这里的 resources 单指 java 的资源
    25. public static final Set<ContentType> CONTENT_RESOURCES;
    26. public static final Set<ContentType> CONTENT_NATIVE_LIBS;
    27. public static final Set<ContentType> CONTENT_DEX;
    28. public static final Set<ContentType> CONTENT_DEX_WITH_RESOURCES;
    29. public static final Set<ContentType> DATA_BINDING_BASE_CLASS_LOG_ARTIFACT;
    30. */
    31. @NonNull
    32. public abstract Set<ContentType> getInputTypes();
    33. /**
    34. * Returns the type(s) of data that is generated by the Transform. This may be more than
    35. * one type.
    36. *
    37. * <p>The default implementation returns {@link #getInputTypes()}.
    38. *
    39. * <p><strong>This must be of type {@link QualifiedContent.DefaultContentType}</strong>
    40. */
    41. @NonNull
    42. public Set<ContentType> getOutputTypes() {
    43. return getInputTypes();
    44. }
    45. /**
    46. * 用于指明 Transform 的作用域
    47. public static final Set<Scope> SCOPE_FULL_PROJECT; // 常用,代表所有 Project
    48. 确定了ContentType和Scope后就确定了该自定义Transform需要处理的资源流。
    49. 比如CONTENT_CLASS和SCOPE_FULL_PROJECT表示了所有项目中java编译成的class组成的资源流。
    50. */
    51. @NonNull
    52. public abstract Set<? super Scope> getScopes();
    53. /**
    54. * Returns the referenced scope(s) for the Transform. These scopes are not consumed by
    55. * the Transform. They are provided as inputs, but are still available as inputs for
    56. * other Transforms to consume.
    57. *
    58. * <p>The default implementation returns an empty Set.
    59. */
    60. @NonNull
    61. public Set<? super Scope> getReferencedScopes() {
    62. return ImmutableSet.of();
    63. }
    64. /**
    65. * Returns a list of additional file(s) that this Transform needs to run. Preferably, use
    66. * {@link #getSecondaryFiles()} API which allow eah secondary file to indicate if changes
    67. * can be handled incrementally or not. This API will treat all additional file change as
    68. * a non incremental event.
    69. *
    70. * <p>Changes to files returned in this list will trigger a new execution of the Transform
    71. * even if the qualified-content inputs haven't been touched.
    72. *
    73. * <p>Any changes to these files will trigger a non incremental execution.
    74. *
    75. * <p>The default implementation returns an empty collection.
    76. *
    77. * @deprecated replaced by {@link #getSecondaryFiles()}
    78. */
    79. @Deprecated
    80. @NonNull
    81. public Collection<File> getSecondaryFileInputs() {
    82. return ImmutableList.of();
    83. }
    84. /**
    85. * Returns a list of additional file(s) that this Transform needs to run.
    86. *
    87. * <p>Changes to files returned in this list will trigger a new execution of the Transform
    88. * even if the qualified-content inputs haven't been touched.
    89. *
    90. * <p>Each secondary input has the ability to be declared as necessitating a non incremental
    91. * execution in case of change. This Transform can therefore declare which secondary file
    92. * changes it supports in incremental mode.
    93. *
    94. * <p>The default implementation returns an empty collection.
    95. */
    96. @NonNull
    97. public Collection<SecondaryFile> getSecondaryFiles() {
    98. return ImmutableList.of();
    99. }
    100. /**
    101. * Returns a list of additional (out of streams) file(s) that this Transform creates.
    102. *
    103. * <p>These File instances can only represent files, not directories. For directories, use
    104. * {@link #getSecondaryDirectoryOutputs()}
    105. *
    106. *
    107. * <p>Changes to files returned in this list will trigger a new execution of the Transform
    108. * even if the qualified-content inputs haven't been touched.
    109. *
    110. * <p>Changes to these output files force a non incremental execution.
    111. *
    112. * <p>The default implementation returns an empty collection.
    113. */
    114. @NonNull
    115. public Collection<File> getSecondaryFileOutputs() {
    116. return ImmutableList.of();
    117. }
    118. /**
    119. * Returns a list of additional (out of streams) directory(ies) that this Transform creates.
    120. *
    121. * <p>These File instances can only represent directories. For files, use
    122. * {@link #getSecondaryFileOutputs()}
    123. *
    124. * <p>Changes to directories returned in this list will trigger a new execution of the Transform
    125. * even if the qualified-content inputs haven't been touched.
    126. *
    127. * <p>Changes to these output directories force a non incremental execution.
    128. *
    129. * <p>The default implementation returns an empty collection.
    130. */
    131. @NonNull
    132. public Collection<File> getSecondaryDirectoryOutputs() {
    133. return ImmutableList.of();
    134. }
    135. /**
    136. * Returns a map of non-file input parameters using a unique identifier as the map key.
    137. *
    138. * <p>Changes to values returned in this map will trigger a new execution of the Transform
    139. * even if the content inputs haven't been touched.
    140. *
    141. * <p>Changes to these values force a non incremental execution.
    142. *
    143. * <p>The default implementation returns an empty Map.
    144. */
    145. @NonNull
    146. public Map<String, Object> getParameterInputs() {
    147. return ImmutableMap.of();
    148. }
    149. /**
    150. * 指明该 Transform 是否支持增量编译。需要注意的是,即使返回了 true ,在某些情况下运行时,它还是会返回 false 的。
    151. */
    152. public abstract boolean isIncremental();
    153. /**
    154. * For Transforms that produce an output available though the [BuildArtifactsHolder] provider
    155. * based interfaces should indicate the output directory of the produced artifact
    156. *
    157. * @param directory
    158. */
    159. public void setOutputDirectory(@NonNull Property<Directory> directory) {}
    160. public void setOutputFile(@NonNull Property<RegularFile> file) {}
    161. /**
    162. * @deprecated replaced by {@link #transform(TransformInvocation)}.
    163. */
    164. @Deprecated
    165. @SuppressWarnings("UnusedParameters")
    166. public void transform(
    167. @NonNull Context context,
    168. @NonNull Collection<TransformInput> inputs,
    169. @NonNull Collection<TransformInput> referencedInputs,
    170. @Nullable TransformOutputProvider outputProvider,
    171. boolean isIncremental) throws IOException, TransformException, InterruptedException {
    172. }
    173. /**
    174. * 其中,inputs 是该 Transform 要消费的输入流,有两种格式:jar 和目录格式;referenced
    175. Inputs 集合仅供参考,不应进行转换,它是受 getReferencedScopes 方法控制的;
    176. outputProvider 是用来获取输出目录的,我们要将操作后的文件复制到输出目录中。
    177. */
    178. public void transform(@NonNull TransformInvocation transformInvocation)
    179. throws TransformException, InterruptedException, IOException {
    180. // Just delegate to old method, for code that uses the old API.
    181. //noinspection deprecation
    182. transform(transformInvocation.getContext(), transformInvocation.getInputs(),
    183. transformInvocation.getReferencedInputs(),
    184. transformInvocation.getOutputProvider(),
    185. transformInvocation.isIncremental());
    186. }
    187. /**
    188. * Returns if this transform's outputs should be cached. Please read {@link
    189. * org.gradle.api.tasks.CacheableTask} Javadoc if you would like to make your transform
    190. * cacheable.
    191. */
    192. public boolean isCacheable() {
    193. return false;
    194. }
    195. }
    1. public interface TransformInvocation {
    2. // 上下文
    3. @NonNull
    4. Context getContext();
    5. // transform 的输入/输出
    6. @NonNull
    7. Collection<TransformInput> getInputs();
    8. // 返回不被这个 transformation 消费的 input
    9. @NonNull Collection<TransformInput> getReferencedInputs();
    10. /**
    11. * Returns the list of secondary file changes since last. Only secondary files that this
    12. * transform can handle incrementally will be part of this change set.
    13. */
    14. @NonNull Collection<SecondaryInput> getSecondaryInputs();
    15. // 返回允许创建内容的 output provider
    16. @Nullable
    17. TransformOutputProvider getOutputProvider();
    18. boolean isIncremental();
    19. }
    1. public interface TransformOutputProvider {
    2. void deleteAll() throws IOException;
    3. // 根据 name、ContentType、QualifiedContent.Scope 返回对应的文件(jar / directory)
    4. @NonNull
    5. File getContentLocation(
    6. @NonNull String name,
    7. @NonNull Set<QualifiedContent.ContentType> types,
    8. @NonNull Set<? super QualifiedContent.Scope> scopes,
    9. @NonNull Format format);
    10. }