Gradle实战-09-Gradle其他模块讲解与自定义Plugin实战

一、学习目标

  • Gradle其他模块
  • Settings类讲解
  • SourceSet类讲解
  • Plugin讲解及自定义Plugin
  • Android插件对Gradle扩展

二、其他模块

Settings 类其实就是帮助我们初始化,决定哪些项目能够被处理

//settings.gradle
include ':buildSrc'
include ':app', ':repository:viewpagerindicator', ':oema', ':oemb'

println '初始化阶段开始....'

SourceSet 决定从哪些目录加载代码和资源文件

gradle约定大于配置,默认约定代码是在 main/java , 默认资源文件是在 main/res下的。

修改默认的jniLibs目录,默认情况下是在 main/jniLibs目录,现在修改成 app/Libs目录

    sourceSets {
        main {
            //对默认的so存放地址改成 app/libs目录
            jniLibs.srcDirs =['libs']
        }
    }

对资源文件按照模块存放

    sourceSets {
        main {
            //分模块存放资源
            res.srcDirs = ['src/main/res',
                           'src/main/res-ad',
                           'src/main/res-player'
            ]
        }
    }

在res目录下创建res-ad,res-player目录,这样可以按照模块进行资源的存放。

注意:sourceSets 是可以多次调用的,即可以重复写多次。sourceSets 可以不在android 闭包中编写的,如下所示:

//利用编程思想 在android模块外进行资源按照模块进行分类
this.android.sourceSets {
    main {
        res.srcDirs = ['src/main/res']
    }
}

这里可以看下com.android.build.gradle包下的AndroidConfig.java 文件,里面包含了android插件的扩展属性,即表明了如何配置android这个扩展。AppExtension.java文件也很重要,要多次看。

 以下就是 AndroidConfig 文件,内容如下:

public interface AndroidConfig {


    /**
     * Specifies the version of the <a
     * href="https://developer.android.com/studio/releases/build-tools.html">SDK Build Tools</a> to
     * use when building your project.
     *
     * <p>When using Android plugin 3.0.0 or later, configuring this property is optional. By
     * default, the plugin uses the minimum version of the build tools required by the <a
     * href="https://developer.android.com/studio/releases/gradle-plugin.html#revisions">version of
     * the plugin</a> you're using. To specify a different version of the build tools for the plugin
     * to use, specify the version as follows:
     *
     * <pre>
     * // Specifying this property is optional.
     * buildToolsVersion "26.0.0"
     * </pre>
     *
     * <p>For a list of build tools releases, read <a
     * href="https://developer.android.com/studio/releases/build-tools.html#notes">the release
     * notes</a>.
     *
     * <p>Note that the value assigned to this property is parsed and stored in a normalized form,
     * so reading it back may give a slightly different result.
     */
    String getBuildToolsVersion();

    /**
     * Specifies the API level to compile your project against. The Android plugin requires you to
     * configure this property.
     *
     * <p>This means your code can use only the Android APIs included in that API level and lower.
     * You can configure the compile sdk version by adding the following to the <code>android</code>
     * block: <code>compileSdkVersion 26</code>.
     *
     * <p>You should generally <a
     * href="https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels">use
     * the most up-to-date API level</a> available. If you are planning to also support older API
     * levels, it's good practice to <a
     * href="https://developer.android.com/studio/write/lint.html">use the Lint tool</a> to check if
     * you are using APIs that are not available in earlier API levels.
     *
     * <p>The value you assign to this property is parsed and stored in a normalized form, so
     * reading it back may return a slightly different value.
     */
    String getCompileSdkVersion();

    /**
     * This property is for internal use only.
     *
     * <p>To specify the version of the <a
     * href="https://developer.android.com/studio/releases/build-tools.html">SDK Build Tools</a>
     * that the Android plugin should use, use <a
     * href="com.android.build.gradle.BaseExtension.html#com.android.build.gradle.BaseExtension:buildToolsVersion">buildToolsVersion</a>
     * instead.
     */
    @Internal
    Revision getBuildToolsRevision();

    /**
     * Specifies the version of the module to publish externally. This property is generally useful
     * only to library modules that you intend to publish to a remote repository, such as Maven.
     *
     * <p>If you don't configure this property, the Android plugin publishes the release version of
     * the module by default. If the module configures <a
     * href="https://developer.android.com/studio/build/build-variants.html#product-flavors">product
     * flavors</a>, you need to configure this property with the name of the variant you want the
     * plugin to publish, as shown below:
     *
     * <pre>
     * // Specifies the 'demoDebug' build variant as the default variant
     * // that the plugin should publish to external consumers.
     * defaultPublishConfig 'demoDebug'
     * </pre>
     *
     * <p>If you plan to only consume your library module locally, you do not need to configure this
     * property. Android plugin 3.0.0 and higher use <a
     * href="https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_aware">variant-aware
     * dependency resolution</a> to automatically match the variant of the producer to that of the
     * consumer. That is, when publishing a module to another local module, the plugin no longer
     * respects this property when determining which version of the module to publish to the
     * consumer.
     */
    String getDefaultPublishConfig();

    /**
     * Specifies variants the Android plugin should include or remove from your Gradle project.
     *
     * <p>By default, the Android plugin creates a build variant for every possible combination of
     * the product flavors and build types that you configure, and adds them to your Gradle project.
     * However, there may be certain build variants that either you do not need or do not make sense
     * in the context of your project. You can remove certain build variant configurations by <a
     * href="https://developer.android.com/studio/build/build-variants.html#filter-variants">creating
     * a variant filter</a> in your module-level <code>build.gradle</code> file.
     *
     * <p>The following example tells the plugin to ignore all variants that combine the "dev"
     * product flavor, which you can configure to <a
     * href="https://developer.android.com/studio/build/optimize-your-build.html#create_dev_variant">optimize
     * build speeds</a> during development, and the "release" build type:
     *
     * <pre>
     * android {
     *     ...
     *     variantFilter { variant -&gt;
     *
     *         def buildTypeName = variant.buildType*.name
     *         def flavorName = variant.flavors*.name
     *
     *         if (flavorName.contains("dev") &amp;&amp; buildTypeName.contains("release")) {
     *             // Tells Gradle to ignore each variant that satisfies the conditions above.
     *             setIgnore(true)
     *         }
     *     }
     * }
     * </pre>
     *
     * <p>During subsequent builds, Gradle ignores any build variants that meet the conditions you
     * specify. If you're using <a href="https://developer.android.com/studio/index.html">Android
     * Studio</a>, those variants no longer appear in the drop down menu when you click <b>Build
     * &gt; Select Build Variant</b> from the menu bar.
     *
     * @see com.android.build.gradle.internal.api.VariantFilter
     */
    Action<VariantFilter> getVariantFilter();

    /**
     * Specifies APK install options for the <a
     * href="https://developer.android.com/studio/command-line/adb.html">Android Debug Bridge
     * (ADB)</a>.
     *
     * @see com.android.build.gradle.internal.dsl.AdbOptions
     */
    AdbOptions getAdbOptions();

    /**
     * Specifies the module's resource prefix to Android Studio for editor features, such as Lint
     * checks. This property is useful only when using Android Studio.
     *
     * <p>Including unique prefixes for module resources helps avoid naming collisions with
     * resources from other modules. For example, when creating a library with String resources, you
     * may want to name each resource with a unique prefix, such as <code>"mylib_"</code> to avoid
     * naming collisions with similar resources that the consumer defines. You can then specify this
     * prefix, as shown below, so that Android Studio expects this prefix when you name module
     * resources:
     *
     * <pre>
     * // This property is useful only when developing your project in Android Studio.
     * resourcePrefix 'mylib_'
     * </pre>
     */
    String getResourcePrefix();

    /**
     * Specifies the names of product flavor dimensions for this project.
     *
     * <p>To configure flavor dimensions, use <a
     * href="com.android.build.gradle.BaseExtension.html#com.android.build.gradle.BaseExtension:flavorDimensions(java.lang.String[])">
     * <code>flavorDimensions</code></a>. To learn more, read <a
     * href="https://developer.android.com/studio/build/build-variants.html#flavor-dimensions">combine
     * multiple product flavors</a>.
     */
    List<String> getFlavorDimensionList();

    /**
     * Specifies whether to build APK splits or multiple APKs from configurations in the {@link
     * com.android.build.gradle.internal.dsl.Splits splits} block.
     *
     * <p>When you set this property to <code>true</code>, the Android plugin generates each object
     * in the {@link com.android.build.gradle.internal.dsl.Splits splits} block as a portion of a
     * whole APK, called an <em>APK split</em>. Compared to building multiple APKs, each APK split
     * includes only the components that each ABI or screen density requires. Generating APK splits
     * is an incubating feature, which requires you to set {@link
     * com.android.build.gradle.internal.dsl.BaseFlavor#minSdkVersion(int)} to <code>21</code> or
     * higher, and is currently supported only when publishing <a
     * href="https://d.android.com/instant-apps">Android Instant Apps</a>.
     *
     * <p>When you do not configure this property or set it to <code>false</code> (default), the
     * Android plugin builds separate APKs for each object you configure in the {@link
     * com.android.build.gradle.internal.dsl.Splits splits} block that you can deploy to a device.
     * To learn more about building different versions of your app that each target a different <a
     * href="https://developer.android.com/ndk/guides/abis.html">Application Binary Interfaces</a>
     * or screen density, read <a
     * href="https://developer.android.com/studio/build/configure-apk-splits.html">Build Multiple
     * APKs</a>.
     */
    @Incubating
    boolean getGeneratePureSplits();

    /**
     * Specifies defaults for variant properties that the Android plugin applies to all build
     * variants.
     *
     * <p>You can override any <code>defaultConfig</code> property when <a
     * href="https://developer.android.com/studio/build/build-variants.html#product-flavors">configuring
     * product flavors</a>.
     *
     * @see com.android.build.gradle.internal.dsl.ProductFlavor
     */
    CoreProductFlavor getDefaultConfig();

    /**
     * Specifies options for the Android Asset Packaging Tool (AAPT).
     *
     * @see com.android.build.gradle.internal.dsl.AaptOptions
     */
    AaptOptions getAaptOptions();

    /**
     * Specifies Java compiler options, such as the language level of the Java source code and
     * generated bytecode.
     *
     * @see com.android.build.gradle.internal.CompileOptions
     */
    CompileOptions getCompileOptions();

    /**
     * Specifies options for the DEX tool, such as enabling library pre-dexing.
     *
     * <p>Experimenting with DEX options tailored for your workstation may improve build
     * performance. To learn more, read <a
     * href="https://developer.android.com/studio/build/optimize-your-build.html#dex_options">Optimize
     * your build</a>.
     *
     * @see com.android.build.gradle.internal.dsl.DexOptions
     */
    DexOptions getDexOptions();

    /**
     * Configure JaCoCo version that is used for offline instrumentation and coverage report.
     *
     * <p>To specify the version of JaCoCo you want to use, add the following to <code>build.gradle
     * </code> file:
     *
     * <pre>
     * android {
     *     jacoco {
     *         version "&lt;jacoco-version&gt;"
     *     }
     * }
     * </pre>
     */
    JacocoOptions getJacoco();

    /**
     * Specifies options for the lint tool.
     *
     * <p>Android Studio and the Android SDK provide a code scanning tool called lint that can help
     * you to identify and correct problems with the structural quality of your code without having
     * to execute the app or write test cases. Each problem the tool detects is reported with a
     * description message and a severity level, so that you can quickly prioritize the critical
     * improvements that need to be made.
     *
     * <p>This property allows you to configure certain lint options, such as which checks to run or
     * ignore. If you're using Android Studio, you can <a
     * href="https://developer.android.com/studio/write/lint.html#cis">configure similar lint
     * options</a> from the IDE. To learn more about using and running lint, read <a
     * href="https://developer.android.com/studio/write/lint.html">Improve Your Code with Lint</a>.
     *
     * @see com.android.build.gradle.internal.dsl.LintOptions
     */
    LintOptions getLintOptions();

    /**
     * Specifies options for external native build using <a href="https://cmake.org/">CMake</a> or
     * <a href="https://developer.android.com/ndk/guides/ndk-build.html">ndk-build</a>.
     *
     * <p>When using <a href="https://developer.android.com/studio/index.html">Android Studio 2.2 or
     * higher</a> with <a
     * href="https://developer.android.com/studio/releases/gradle-plugin.html">Android plugin 2.2.0
     * or higher</a>, you can compile C and C++ code into a native library that Gradle packages into
     * your APK.
     *
     * <p>To learn more, read <a
     * href="https://developer.android.com/studio/projects/add-native-code.html">Add C and C++ Code
     * to Your Project</a>.
     *
     * @see com.android.build.gradle.internal.dsl.ExternalNativeBuild
     * @since 2.2.0
     */
    CoreExternalNativeBuild getExternalNativeBuild();

    /**
     * Specifies options and rules that determine which files the Android plugin packages into your
     * APK.
     *
     * <p>For example, the following example tells the plugin to avoid packaging files that are
     * intended only for testing:
     *
     * <pre>
     * packagingOptions {
     *     // Tells the plugin to not include any files in the 'testing-data/' directory,
     *     // which is specified as an absolute path from the root of the APK archive.
     *     // The exclude property includes certain defaults paths to help you avoid common
     *     // duplicate file errors when building projects with multiple dependencies.
     *     exclude "/testing-data/**"
     * }
     * </pre>
     *
     * <p>To learn more about how to specify rules for packaging, merging, and excluding files, see
     * {@link PackagingOptions}
     *
     * @see com.android.build.gradle.internal.dsl.PackagingOptions
     */
    PackagingOptions getPackagingOptions();

    /**
     * Specifies configurations for <a
     * href="https://developer.android.com/studio/build/configure-apk-splits.html">building multiple
     * APKs</a> or APK splits.
     *
     * <p>To generate APK splits, you need to also set <a
     * href="com.android.build.gradle.BaseExtension.html#com.android.build.gradle.BaseExtension:generatePureSplits">
     * <code>generatePureSplits</code></a> to <code>true</code>. However, generating APK splits is
     * an incubating feature, which requires you to set {@link
     * com.android.build.gradle.internal.dsl.BaseFlavor#minSdkVersion(int)} to <code>21</code> or
     * higher, and is currently supported only when publishing <a
     * href="https://d.android.com/instant-apps">Android Instant Apps</a>.
     *
     * @see com.android.build.gradle.internal.dsl.Splits
     */
    Splits getSplits();

    /**
     * Specifies options for how the Android plugin should run local and instrumented tests.
     *
     * <p>To learn more, read <a
     * href="https://developer.android.com/studio/test/index.html#test_options">Configure Gradle
     * test options</a>.
     *
     * @see com.android.build.gradle.internal.dsl.TestOptions
     */
    TestOptions getTestOptions();

    /** List of device providers */
    @NonNull
    List<DeviceProvider> getDeviceProviders();

    /** List of remote CI servers. */
    @NonNull
    List<TestServer> getTestServers();

    @NonNull
    List<Transform> getTransforms();
    @NonNull
    List<List<Object>> getTransformsDependencies();

    /**
     * Encapsulates all product flavors configurations for this project.
     *
     * <p>Product flavors represent different versions of your project that you expect to co-exist
     * on a single device, the Google Play store, or repository. For example, you can configure
     * 'demo' and 'full' product flavors for your app, and each of those flavors can specify
     * different features, device requirements, resources, and application ID's--while sharing
     * common source code and resources. So, product flavors allow you to output different versions
     * of your project by simply changing only the components and settings that are different
     * between them.
     *
     * <p>Configuring product flavors is similar to <a
     * href="https://developer.android.com/studio/build/build-variants.html#build-types">configuring
     * build types</a>: add them to the <code>productFlavors</code> block of your module's <code>
     * build.gradle</code> file and configure the settings you want. Product flavors support the
     * same properties as the {@link com.android.build.gradle.internal.dsl.DefaultConfig}
     * block--this is because <code>defaultConfig</code> defines a {@link
     * com.android.build.gradle.internal.dsl.ProductFlavor} object that the plugin uses as the base
     * configuration for all other flavors. Each flavor you configure can then override any of the
     * default values in <code>defaultConfig</code>, such as the <a
     * href="https://d.android.com/studio/build/application-id.html"><code>applicationId</code></a>.
     *
     * <p>When using Android plugin 3.0.0 and higher, <em>each flavor must belong to a <a
     * href="com.android.build.gradle.BaseExtension.html#com.android.build.gradle.BaseExtension:flavorDimensions(java.lang.String[])">
     * <code>flavorDimensions</code></a> value</em>. By default, when you specify only one
     * dimension, all flavors you configure belong to that dimension. If you specify more than one
     * flavor dimension, you need to manually assign each flavor to a dimension. To learn more, read
     * <a
     * href="https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_aware">
     * Use Flavor Dimensions for variant-aware dependency management</a>.
     *
     * <p>When you configure product flavors, the Android plugin automatically combines them with
     * your {@link com.android.build.gradle.internal.dsl.BuildType} configurations to <a
     * href="https://developer.android.com/studio/build/build-variants.html">create build
     * variants</a>. If the plugin creates certain build variants that you don't want, you can <a
     * href="https://developer.android.com/studio/build/build-variants.html#filter-variants">filter
     * variants</a>.
     *
     * @see com.android.build.gradle.internal.dsl.ProductFlavor
     */
    Collection<? extends CoreProductFlavor> getProductFlavors();

    /**
     * Encapsulates all build type configurations for this project.
     *
     * <p>Unlike using {@link com.android.build.gradle.internal.dsl.ProductFlavor} to create
     * different versions of your project that you expect to co-exist on a single device, build
     * types determine how Gradle builds and packages each version of your project. Developers
     * typically use them to configure projects for various stages of a development lifecycle. For
     * example, when creating a new project from Android Studio, the Android plugin configures a
     * 'debug' and 'release' build type for you. By default, the 'debug' build type enables
     * debugging options and signs your APK with a generic debug keystore. Conversely, The 'release'
     * build type strips out debug symbols and requires you to <a
     * href="https://developer.android.com/studio/publish/app-signing.html#sign-apk">create a
     * release key and keystore</a> for your app. You can then combine build types with product
     * flavors to <a href="https://developer.android.com/studio/build/build-variants.html">create
     * build variants</a>.
     *
     * @see com.android.build.gradle.internal.dsl.BuildType
     */
    Collection<? extends CoreBuildType> getBuildTypes();

    /**
     * Encapsulates signing configurations that you can apply to {@link
     * com.android.build.gradle.internal.dsl.BuildType} and {@link
     * com.android.build.gradle.internal.dsl.ProductFlavor} configurations.
     *
     * <p>Android requires that all APKs be digitally signed with a certificate before they can be
     * installed onto a device. When deploying a debug version of your project from Android Studio,
     * the Android plugin automatically signs your APK with a generic debug certificate. However, to
     * build an APK for release, you must <a
     * href="https://developer.android.com/studio/publish/app-signing.html">sign the APK</a> with a
     * release key and keystore. You can do this by either <a
     * href="https://developer.android.com/studio/publish/app-signing.html#sign-apk">using the
     * Android Studio UI</a> or manually <a
     * href="https://developer.android.com/studio/publish/app-signing.html#gradle-sign">configuring
     * your <code>build.gradle</code> file</a>.
     *
     * @see com.android.build.gradle.internal.dsl.SigningConfig
     */
    Collection<? extends SigningConfig> getSigningConfigs();

    /**
     * Encapsulates source set configurations for all variants.
     *
     * <p>The Android plugin looks for your project's source code and resources in groups of
     * directories called <i><a
     * href="https://developer.android.com/studio/build/index.html#sourcesets">source sets</a></i>.
     * Each source set also determines the scope of build outputs that should consume its code and
     * resources. For example, when creating a new project from Android Studio, the IDE creates
     * directories for a <code>main/</code> source set that contains the code and resources you want
     * to share between all your build variants.
     *
     * <p>You can then define basic functionality in the <code>main/</code> source set, but use
     * product flavor source sets to change only the branding of your app between different clients,
     * or include special permissions and logging functionality to only "debug" versions of your
     * app.
     *
     * <p>The Android plugin expects you to organize files for source set directories a certain way,
     * similar to the <code>main/</code> source set. For example, Gradle expects Java class files
     * that are specific to your "debug" build type to be located in the <code>src/debug/java/
     * </code> directory.
     *
     * <p>Gradle provides a useful task to shows you how to organize your files for each build
     * type-, product flavor-, and build variant-specific source set. you can run this task from the
     * command line as follows:
     *
     * <pre>./gradlew sourceSets</pre>
     *
     * <p>The following sample output describes where Gradle expects to find certain files for the
     * "debug" build type:
     *
     * <pre>
     * ------------------------------------------------------------
     * Project :app
     * ------------------------------------------------------------
     *
     * ...
     *
     * debug
     * ----
     * Compile configuration: compile
     * build.gradle name: android.sourceSets.debug
     * Java sources: [app/src/debug/java]
     * Manifest file: app/src/debug/AndroidManifest.xml
     * Android resources: [app/src/debug/res]
     * Assets: [app/src/debug/assets]
     * AIDL sources: [app/src/debug/aidl]
     * RenderScript sources: [app/src/debug/rs]
     * JNI sources: [app/src/debug/jni]
     * JNI libraries: [app/src/debug/jniLibs]
     * Java-style resources: [app/src/debug/resources]
     * </pre>
     *
     * <p>If you have sources that are not organized into the default source set directories that
     * Gradle expects, as described in the sample output above, you can use the <code>sourceSet
     * </code> block to change where Gradle looks to gather files for each component of a given
     * source set. You don't need to relocate the files; you only need to provide Gradle with the
     * path(s), relative to the module-level <code>build.gradle</code> file, where Gradle should
     * expect to find files for each source set component.
     *
     * <p><b>Note:</b> You should specify only static paths whenever possible. Specifying dynamic
     * paths reduces build speed and consistency.
     *
     * <p>The following code sample maps sources from the <code>app/other/</code> directory to
     * certain components of the <code>main</code> source set and changes the root directory of the
     * <code>androidTest</code> source set:
     *
     * <pre>
     * android {
     *   ...
     *   sourceSets {
     *     // Encapsulates configurations for the main source set.
     *     main {
     *         // Changes the directory for Java sources. The default directory is
     *         // 'src/main/java'.
     *         java.srcDirs = ['other/java']
     *
     *         // If you list multiple directories, Gradle uses all of them to collect
     *         // sources. Because Gradle gives these directories equal priority, if
     *         // you define the same resource in more than one directory, you get an
     *         // error when merging resources. The default directory is 'src/main/res'.
     *         res.srcDirs = ['other/res1', 'other/res2']
     *
     *         // Note: You should avoid specifying a directory which is a parent to one
     *         // or more other directories you specify. For example, avoid the following:
     *         // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
     *         // You should specify either only the root 'other/res1' directory, or only the
     *         // nested 'other/res1/layouts' and 'other/res1/strings' directories.
     *
     *         // For each source set, you can specify only one Android manifest.
     *         // By default, Android Studio creates a manifest for your main source
     *         // set in the src/main/ directory.
     *         manifest.srcFile 'other/AndroidManifest.xml'
     *         ...
     *     }
     *
     *     // Create additional blocks to configure other source sets.
     *     androidTest {
     *         // If all the files for a source set are located under a single root
     *         // directory, you can specify that directory using the setRoot property.
     *         // When gathering sources for the source set, Gradle looks only in locations
     *         // relative to the root directory you specify. For example, after applying the
     *         // configuration below for the androidTest source set, Gradle looks for Java
     *         // sources only in the src/tests/java/ directory.
     *         setRoot 'src/tests'
     *         ...
     *     }
     *   }
     * }
     * </pre>
     *
     * @see com.android.build.gradle.internal.dsl.AndroidSourceSetFactory
     */
    NamedDomainObjectContainer<AndroidSourceSet> getSourceSets();

    /** build outputs for all variants */
    Collection<BaseVariantOutput> getBuildOutputs();

    /** Whether to package build config class file. */
    Boolean getPackageBuildConfig();

    /** Aidl files to package in the aar. */
    Collection<String> getAidlPackageWhiteList();

    Collection<LibraryRequest> getLibraryRequests();

    /**
     * Specifies options for the <a
     * href="https://developer.android.com/topic/libraries/data-binding/index.html">Data Binding
     * Library</a>.
     *
     * <p>Data binding helps you write declarative layouts and minimize the glue code necessary to
     * bind your application logic and layouts.
     */
    DataBindingOptions getDataBinding();

    /** Whether the feature module is the base feature. */
    Boolean getBaseFeature();

    /**
     * Name of the build type that will be used when running Android (on-device) tests.
     *
     * <p>Defaults to "debug".
     *
     * <p>FIXME this should not be here, but it has to be because of gradle-core not knowing
     * anything besides this interface. This will be fixed with the new gradle-api based extension
     * interfaces.
     */
    @Nullable
    String getTestBuildType();
}

仔细观察以上的内容,去掉 get 之后改首字母小写就可以得到相关的配置选项。

三、自定义插件

自定义插件是对Gradle的扩展,可以在任意项目中添加新的任务,这样有一个好处就是这个task是在其他人提供的插件里带的,那么这个插件的功能就会给我们自己的项目代码其他特殊的功能,这样就可以做到结耦,使得 task 不一定写在自己的项目中。

其实有两种自定义插件的写法,分别如下:

方法一:app/build.gradle 文件中编写插件

在 app/build.gradle 文件中编写插件

//app/build.gradle
class CustomPlugin implements Plugin<Project>{

    @Override
    void apply(Project project) {
        project.task('customTask'){
            doLast{
              println "这是一个通过自定义插件方式创建的任务"
            }  
        }
    }
}

在 build.gradle 顶部导入插件
#apply plugin: 'com.android.application'
apply plugin: CustomPlugin

我们在使用的时候 其实还是按照任务的名称来执行任务
// 比如 ./gradlew customTask

方法二:在buildSrc 中创建插件

在项目中编写插件 即在buildSrc 中创建插件

1. 在项目根目录下创建名为 buildSrc 的 Android Library 【可能会buildSrc是保留的项目名称,杂事不用管】,创建之后在 settings.gradle 文件中添加该工程  include ':buildSrc' ,同步之后会发现项目的颜色变蓝,说明配置成功。

2. 在 buildSrc 目录下只保留 src/main 目录,保留 build.gradle文件 ,创建 resources 目录,删除清单文件。整体结构如下:

3. 修改 build.gradle 文件内容如下所示:

apply plugin: 'groovy'

dependencies {
    // gradle sdk
    implementation gradleApi()
    // groovy sdk
    implementation localGroovy()

    //添加依赖,于Android一样
    implementation "com.android.tools.build:gradle:3.1.2"
    //implementation "com.android.tools.build:transform-api:1.5.0"
    //implementation "javassist:javassist:3.12.1.GA"
    //implementation "commons-io:commons-io:2.6"
}

repositories {
    google()
    mavenCentral()
}

4. 修改 main 目录下的 java 目录名称为 groovy,并创建包名 com.luckyboy.customplugin的包,准备开始创建自定义插件。

5. 在创建好的包下面开始自定义插件,创建一个名为 MyPlugin的 groovy 文件,内容如下:

package com.luckyboy.customplugin;

import org.gradle.api.Plugin;
import org.gradle.api.Project;

class MyPlugin implements Plugin<Project> {

    @Override
    public void apply(Project project) {
        project.task("myPluginTask"){
            dependsOn('initTask') // initTask 是我们在 app/build.gradle中创建的Task
            doLast {
                println "我是在buildSrc文件中创建的Gradle插件"
            }
        };
    }
}

6. 在之前创建好的 resources 目录下创建 META-INF/gradle-plugins 目录,注意目录名不能写错。

7. 在 gradle-plugins 目录下创建名为 net.wequick.small.properties 文件,该文件名称在后面作为插件名称使用【net.wequick.small】。内容如下:

#implementation-class后面跟的是我们自定义的插件类全路径名
implementation-class=com.luckyboy.customplugin.MyPlugin 

8. 在 app/build.gradle 文件中引入插件

apply plugin: 'com.android.application'
apply plugin: 'net.wequick.small'

9. 查看下之前提到的 initTask 任务【在 app/build.gradle文件中定义】<< 相当于 doLast

task initTask {
     doLast {
         println("恭喜发财!!")
     }
}

10. 在Terminal 中执行命令 ./gradlew myPluginTask 

zfz:Maven zhangfengzhou$ ./gradlew myPluginTask

> Configure project :lib_music
lib_music AfterEvaluate...

> Task :app:initTask
恭喜发财!!

> Task :app:myPluginTask
我是在buildSrc文件中创建的Gradle插件

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
See https://docs.gradle.org/4.8.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed

如上可以看到创建的 initTask 是先被执行的,然后才是 myPluginTask 任务。

四、总结

本篇总结了Gradle的其他模块,比如 settings、sourceSets等,还有自定义插件,自定义插件就是在其他模块中进行任务的定义,可以解耦任务与项目,一个插件可以在多个项目中使用,比如将这个插件上传到私有仓库,那么在项目中使用该插件的时候,就可以不用单独把插件源码拷贝一份来使用,直接下载插件和使用插件即可。本文中的插件都是做在本地的,没有上传仓库,后面会介绍上传插件到仓库并使用的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值