I wrote one beforeGradle_05 custom plug-inThis one is a review

Gradle plug-ins are written to extract and encapsulate logically independent code

The basic use

1. Now add the following code under app/build.gradle:

  • DshPlugin is a plug-in we wrote ourselves
  • DshExtension is an extension, and we can create an extension named dshE
  • Run the. Gradlew command to print “Hello android Gradle extension”.
    // implements plugin <Project>{@override void apply(Project target) {def extension = target.extensions.create('dshE',dshExtension) println("Hello ${extension.name}") } } class dshExtension{ def Name = 'android Gradle extension'}Copy the code

2. If we want to change the value of name, we can use a closure of the alias dshE

DshE {name 'dsh_gradle'} -> name('dsh_gradle')->setName('dsh_gradle')}Copy the code
  • This does not output the modified value, however, we need to output afterEvaluate after the task has executed
class dshPlugin implements Plugin<Project>{ @Override void apply(Project target) { def extension = Target.extensions. Create ('dshE',dshExtension) println("Hello ${extension.name}") AfterEvaluate {println("Hello ${extension.name}") : dsh_gradle}}Copy the code

3. At this point, we have written a simple plug-in, but this is obviously awkward to write in our Gradle file. Our goal is to use and configure the plugin easily with just one line of Apply code, apply Plugin :dshPlugin, so we need to change the way. Write plug-ins that are easy to use

Custom plug-in

Create a new buildSrc directory in your project. This is the default directory for the Android plug-in, and the directory structure looks like this

  • Resources/meta-inf /gradle-plugins/*.properties = com.dshplugin.properties = com.dshplugin.properties
    • apply plugin: 'com.dshPlugin'
  • *.properties has only one line in the format:
    • implementation-class=com.dsh.plugin.DshPlugin
    • The right side of the equals sign specifies which class Plugin is
  • Plugin and Extension are written in the buildSrc directory as they are in build.gradle
    • This is a special directory for Gradle. Build. gradle in this directory is automatically executed, i.e. settings.gradle is not configured. (In fact, since Gradle 6.0, buildSrc has become a reserved word and the projects you configure in settings.gradle are not allowed to be called buildSrc.)
    • BuildSrc plugins are automatically added to the classpath of each project during compilation, so they can be easily applied using the Apply Plugin: ‘XXX’ formula

This code runs exactly as if it were written in build.gradle

Transform

  • What is it: a tool provided by Android that adds custom intermediate processing to compiled files (JAR files and class files) during a project build
  • How to write
    • Add the dependencies first :buildSrc/build.gradle
      Dependencies jcenter repositories {Google () ()} {implementation 'com. Android. View the build: gradle: 3.5.4'} SourceCompatibility = "1.7" targetCompatibility = "1.7"Copy the code
    • Then inherits com. Android. Build. API. The transform. Transform, create a subclass:
      class DshTransform extends Transform {
        @Override
        String getName() {
          return 'dshTransform'
        }
      
        @Override
        Set<QualifiedContent.ContentType> getInputTypes() {
          return TransformManager.CONTENT_CLASS
        }
      
        @Override
        Set<? super QualifiedContent.Scope> getScopes() {
          return TransformManager.SCOPE_FULL_PROJECT
        }
      
        @Override
        boolean isIncremental() {
          return false
        }
      
        @Override
        void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
          def inputs = transformInvocation.inputs
          def outputProvider = transformInvocation.outputProvider
          inputs.each {
            it.jarInputs.each {
              File dest = outputProvider.getContentLocation(it.name, it.contentTypes, it.scopes, Format.JAR)
              println "Jar: ${it.file}, Dest: ${dest}"
              FileUtils.copyFile(it.file, dest)
            }
            it.directoryInputs.each {
              File dest = outputProvider.getContentLocation(it.name, it.contentTypes, it.scopes, Format.DIRECTORY)
              println "Dir: ${it.file}, Dest: ${dest}"
              FileUtils.copyDirectory(it.file, dest)
            }
          }
        }
      }
      
      Copy the code
    • What else you can do: Modify the bytecode above the code just move the compiled content to the target location, there is no practical use. To modify the bytecode, you need to introduce other tools, such as Javassist. Tutorials for using Javassist are available online, so you can search for them.