Gradle的settings.gradle.kts你真的理解吗?

你还在用.gradle文件吗?例如build.gradle、settings.gradle,那么你就out了。现在我们有必要了解一下kts脚本了。在Android项目中,默认有3个文件可以替换成kts脚本,即project的build.gradle、app模块的build.gradle和project的settings.gradle,它们更名后分别为build.gradle.kts、build.gradle.kts和settings.gradle.kts。

settings.gradle简介

我们的gradle脚本本质上是执行一个个gradle plugin,即apply plugin,可以执行外部导入的,也可以执行项目编写的编译脚本代码。所以settings.gradle.kts也是编译过程中一个gradle plugin。在
org.gradle.initialization.DefaultSettings中有个getSettings方法,调用这个方法拿到我们配置的settings gradle plugin。settings.gradle.kts中可以配置的内容我们参考Settings这个类。在settings.gradle.kts这个文件中,主要配置一些项目全局的设置。

Settings全局设置解析

package org.gradle.api.initialization;import org.gradle.StartParameter;
import org.gradle.api.Action;
import org.gradle.api.Incubating;
import org.gradle.api.UnknownProjectException;
import org.gradle.api.initialization.dsl.ScriptHandler;
import org.gradle.api.initialization.resolve.DependencyResolutionManagement;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.plugins.ExtensionAware;
import org.gradle.api.plugins.PluginAware;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.toolchain.management.ToolchainManagement;
import org.gradle.api.cache.CacheConfigurations;
import org.gradle.caching.configuration.BuildCacheConfiguration;
import org.gradle.internal.HasInternalProtocol;
import org.gradle.plugin.management.PluginManagementSpec;
import org.gradle.vcs.SourceControl;import javax.annotation.Nullable;
import java.io.File;
import java.util.Arrays;/*** <p>Declares the configuration required to instantiate and configure the hierarchy of {@link* org.gradle.api.Project} instances which are to participate in a build.</p>** <p>There is a one-to-one correspondence between a <code>Settings</code> instance and a <code>{@value* #DEFAULT_SETTINGS_FILE}</code> settings file. Before Gradle assembles the projects for a build, it creates a* <code>Settings</code> instance and executes the settings file against it.</p>** <h3>Assembling a Multi-Project Build</h3>** <p>One of the purposes of the <code>Settings</code> object is to allow you to declare the projects which are to be* included in the build. You add projects to the build using the {@link #include(String...)} method.  There is always a* root project included in a build.  It is added automatically when the <code>Settings</code> object is created.  The* root project's name defaults to the name of the directory containing the settings file. The root project's project* directory defaults to the directory containing the settings file.</p>** <p>When a project is included in the build, a {@link ProjectDescriptor} is created. You can use this descriptor to* change the default values for several properties of the project.</p>** <h3>Using Settings in a Settings File</h3>** <h4>Dynamic Properties</h4>** <p>In addition to the properties of this interface, the {@code Settings} object makes some additional read-only* properties available to the settings script. This includes properties from the following sources:</p>** <ul>** <li>Defined in the {@value org.gradle.api.Project#GRADLE_PROPERTIES} file located in the settings directory of the* build.</li>** <li>Defined the {@value org.gradle.api.Project#GRADLE_PROPERTIES} file located in the user's {@code .gradle}* directory.</li>** <li>Provided on the command-line using the -P option.</li>** </ul>*/
@HasInternalProtocol
public interface Settings extends PluginAware, ExtensionAware {/*** <p>The default name for the settings file.</p>*/String DEFAULT_SETTINGS_FILE = "settings.gradle";/*** <p>Adds the given projects to the build. Each path in the supplied list is treated as the path of a project to* add to the build. Note that these path are not file paths, but instead specify the location of the new project in* the project hierarchy. As such, the supplied paths must use the ':' character as separator (and NOT '/').</p>** <p>The last element of the supplied path is used as the project name. The supplied path is converted to a project* directory relative to the root project directory. The project directory can be altered by changing the 'projectDir'* property after the project has been included (see {@link ProjectDescriptor#setProjectDir(File)})</p>** <p>As an example, the path {@code a:b} adds a project with path {@code :a:b}, name {@code b} and project* directory {@code $rootDir/a/b}. It also adds the a project with path {@code :a}, name {@code a} and project* directory {@code $rootDir/a}, if it does not exist already.</p>** <p>Some common examples of using the project path are:</p>** <pre class='autoTestedSettings'>*   // include two projects, 'foo' and 'foo:bar'*   // directories are inferred by replacing ':' with '/'*   include 'foo:bar'**   // include one project whose project dir does not match the logical project path*   include 'baz'*   project(':baz').projectDir = file('foo/baz')**   // include many projects whose project dirs do not match the logical project paths*   file('subprojects').eachDir { dir -&gt;*     include dir.name*     project(":${dir.name}").projectDir = dir*   }* </pre>** @param projectPaths the projects to add.*/default void include(String... projectPaths) {include(Arrays.asList(projectPaths));}/*** <p>Adds the given projects to the build. Each path in the supplied list is treated as the path of a project to* add to the build. Note that these path are not file paths, but instead specify the location of the new project in* the project hierarchy. As such, the supplied paths must use the ':' character as separator (and NOT '/').</p>** <p>The last element of the supplied path is used as the project name. The supplied path is converted to a project* directory relative to the root project directory. The project directory can be altered by changing the 'projectDir'* property after the project has been included (see {@link ProjectDescriptor#setProjectDir(File)})</p>** <p>As an example, the path {@code a:b} adds a project with path {@code :a:b}, name {@code b} and project* directory {@code $rootDir/a/b}. It also adds the a project with path {@code :a}, name {@code a} and project* directory {@code $rootDir/a}, if it does not exist already.</p>** <p>Some common examples of using the project path are:</p>** <pre class='autoTestedSettings'>*   // include two projects, 'foo' and 'foo:bar'*   // directories are inferred by replacing ':' with '/'*   include(['foo:bar'])**   // include one project whose project dir does not match the logical project path*   include(['baz'])*   project(':baz').projectDir = file('foo/baz')**   // include many projects whose project dirs do not match the logical project paths*   file('subprojects').eachDir { dir -&gt;*     include([dir.name])*     project(":${dir.name}").projectDir = dir*   }* </pre>** @param projectPaths the projects to add.** @since 7.4*/void include(Iterable<String> projectPaths);/*** <p>Adds the given projects to the build. Each name in the supplied list is treated as the name of a project to* add to the build.</p>** <p>The supplied name is converted to a project directory relative to the <em>parent</em> directory of the root* project directory.</p>** <p>As an example, the name {@code a} add a project with path {@code :a}, name {@code a} and project directory* {@code $rootDir/../a}.</p>** @param projectNames the projects to add.*/default void includeFlat(String... projectNames) {includeFlat(Arrays.asList(projectNames));}/*** <p>Adds the given projects to the build. Each name in the supplied list is treated as the name of a project to* add to the build.</p>** <p>The supplied name is converted to a project directory relative to the <em>parent</em> directory of the root* project directory.</p>** <p>As an example, the name {@code a} add a project with path {@code :a}, name {@code a} and project directory* {@code $rootDir/../a}.</p>** @param projectNames the projects to add.** @since 7.4*/void includeFlat(Iterable<String> projectNames);/*** <p>Returns this settings object.</p>** @return This settings object. Never returns null.*/Settings getSettings();/*** Returns the build script handler for settings. You can use this handler to query details about the build* script for settings, and manage the classpath used to compile and execute the settings script.** @return the classpath handler. Never returns null.** @since 4.4*/ScriptHandler getBuildscript();/*** <p>Returns the settings directory of the build. The settings directory is the directory containing the settings* file.</p>** @return The settings directory. Never returns null.*/File getSettingsDir();/*** <p>Returns the root directory of the build. The root directory is the project directory of the root project.</p>** @return The root directory. Never returns null.*/File getRootDir();/*** <p>Returns the root project of the build.</p>** @return The root project. Never returns null.*/ProjectDescriptor getRootProject();/*** <p>Returns the project with the given path.</p>** @param path The path.* @return The project with the given path. Never returns null.* @throws UnknownProjectException If no project with the given path exists.*/ProjectDescriptor project(String path) throws UnknownProjectException;/*** <p>Returns the project with the given path.</p>** @param path The path* @return The project with the given path. Returns null if no such project exists.*/@NullableProjectDescriptor findProject(String path);/*** <p>Returns the project with the given project directory.</p>** @param projectDir The project directory.* @return The project with the given project directory. Never returns null.* @throws UnknownProjectException If no project with the given path exists.*/ProjectDescriptor project(File projectDir) throws UnknownProjectException;/*** <p>Returns the project with the given project directory.</p>** @param projectDir The project directory.* @return The project with the given project directory. Returns null if no such project exists.*/@NullableProjectDescriptor findProject(File projectDir);/*** <p>Returns the set of parameters used to invoke this instance of Gradle.</p>** @return The parameters. Never returns null.*/StartParameter getStartParameter();/*** Provides access to methods to create various kinds of {@link Provider} instances.** @since 6.8*/ProviderFactory getProviders();/*** Returns the {@link Gradle} instance for the current build.** @return The Gradle instance. Never returns null.*/Gradle getGradle();/*** Includes a build at the specified path to the composite build.* @param rootProject The path to the root project directory for the build.** @since 3.1*/void includeBuild(Object rootProject);/*** Includes a build at the specified path to the composite build, with the supplied configuration.* @param rootProject The path to the root project directory for the build.* @param configuration An action to configure the included build.** @since 3.1*/void includeBuild(Object rootProject, Action<ConfigurableIncludedBuild> configuration);/*** Returns the build cache configuration.** @since 3.5*/BuildCacheConfiguration getBuildCache();/*** Configures build cache.** @since 3.5*/void buildCache(Action<? super BuildCacheConfiguration> action);/*** Configures plugin management.** @since 3.5*/void pluginManagement(Action<? super PluginManagementSpec> pluginManagementSpec);/*** Returns the plugin management configuration.** @since 3.5*/PluginManagementSpec getPluginManagement();/*** Configures source control.** @since 4.4*/void sourceControl(Action<? super SourceControl> configuration);/*** Returns the source control configuration.** @since 4.4*/SourceControl getSourceControl();/*** Enables a feature preview by name.** @param name the name of the feature to enable** @since 4.6*/void enableFeaturePreview(String name);/*** Configures the cross-project dependency resolution aspects* @param dependencyResolutionConfiguration the configuration** @since 6.8*/void dependencyResolutionManagement(Action<? super DependencyResolutionManagement> dependencyResolutionConfiguration);/*** Returns the dependency resolution management handler.** @since 6.8*/DependencyResolutionManagement getDependencyResolutionManagement();/*** Configures toolchain management.** @since 7.6*/@Incubatingvoid toolchainManagement(Action<? super ToolchainManagement> toolchainManagementConfiguration);/*** Returns the toolchain management configuration.** @since 7.6*/@IncubatingToolchainManagement getToolchainManagement();/*** Returns the configuration for caches stored in the user home directory.** @since 8.0*/@IncubatingCacheConfigurations getCaches();/*** Configures the settings for caches stored in the user home directory.** @param cachesConfiguration the configuration** @since 8.0*/@Incubatingvoid caches(Action<? super CacheConfigurations> cachesConfiguration);
}

比如要索引哪些模块。

include(":app")

以及项目的编译期间的名称。

rootProject.name = "DoraMusic"

PluginManagementSpec插件管理规格

我们可以看到,在这里我们还可以配置pluginManagement函数,pluginManagement传入的是一个PluginManagementSpec。

package org.gradle.plugin.management;import org.gradle.api.Action;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import org.gradle.api.initialization.ConfigurableIncludedPluginBuild;
import org.gradle.internal.HasInternalProtocol;
import org.gradle.plugin.use.PluginDependenciesSpec;/*** Configures how plugins are resolved.** @since 3.5*/
@HasInternalProtocol
public interface PluginManagementSpec {/*** Defines the plugin repositories to use.*/void repositories(Action<? super RepositoryHandler> repositoriesAction);/*** The plugin repositories to use.*/RepositoryHandler getRepositories();/*** Configure the plugin resolution strategy.*/void resolutionStrategy(Action<? super PluginResolutionStrategy> action);/*** The plugin resolution strategy.*/PluginResolutionStrategy getResolutionStrategy();/*** Configure the default plugin versions.* @since 5.6*/void plugins(Action<? super PluginDependenciesSpec> action);/*** The Plugin dependencies, permitting default plugin versions to be configured.* @since 5.6*/PluginDependenciesSpec getPlugins();/*** Includes a plugin build at the specified path to the composite build.* Included plugin builds can contribute settings and project plugins.* @param rootProject The path to the root project directory for the build.** @since 7.0*/void includeBuild(String rootProject);/*** Includes a plugin build at the specified path to the composite build, with the supplied configuration.* Included plugin builds can contribute settings and project plugins.* @param rootProject The path to the root project directory for the build.* @param configuration An action to configure the included build.** @since 7.0*/void includeBuild(String rootProject, Action<ConfigurableIncludedPluginBuild> configuration);}

在PluginManagementSpec的源码中,我们可以得知,这个高阶函数传入的block可以配置repositories、resolutionStrategy、plugins、includeBuild这几个函数。我们用的比较多的是前面三个。我们再细看repositories,需要传入的是Action<? super RepositoryHandler>,那么问题来了,我明明是要传入的Action,怎么编译器提示的是Action里面的泛型类。
比如:

pluginManagement {repositories {gradlePluginPortal()google()mavenCentral()maven { setUrl("xxx")}
}

截屏2023-08-27 21.11.10.png

不信你就看,this指代的是RepositoryHandler。我们观摩一下Action类。

package org.gradle.api;/*** Performs some action against objects of type T.** @param <T> The type of object which this action accepts.*/
@HasImplicitReceiver
public interface Action<T> {/*** Performs this action against the given object.** @param t The object to perform the action on.*/void execute(T t);
}

如果你理解T.() -> Unit,那么就会很好理解这个概念了。这里其实是kotlin的一个高级的用法,SAM接口。Kotlin中的SAM接口是指"Single Abstract Method"接口,它也被称为函数式接口。在Kotlin中,可以使用lambda表达式来代替这些只有一个抽象方法的接口。通过使用lambda表达式,可以更简洁地表示函数或方法。

Kotlin的SAM转换是指将lambda表达式转换为这些SAM接口的实例,从而可以像使用普通函数一样使用它们。这在使用Java的库或与Java代码交互时特别有用,因为在Java中,通常需要使用匿名内部类来实现SAM接口,而在Kotlin中可以直接使用lambda表达式。

例如,如果有一个只有一个抽象方法的Java接口OnClickListener,在Kotlin中可以这样使用lambda表达式来代替:

button.setOnClickListener { view ->// 点击事件的处理逻辑
}

这样我们就好理解为什么这么配置RepositoryHandler了。

/** Copyright 2009 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
package org.gradle.api.artifacts.dsl;import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
import org.gradle.api.Action;
import org.gradle.api.artifacts.ArtifactRepositoryContainer;
import org.gradle.api.artifacts.repositories.ArtifactRepository;
import org.gradle.api.artifacts.repositories.ExclusiveContentRepository;
import org.gradle.api.artifacts.repositories.FlatDirectoryArtifactRepository;
import org.gradle.api.artifacts.repositories.IvyArtifactRepository;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.internal.HasInternalProtocol;import java.util.Map;/*** A {@code RepositoryHandler} manages a set of repositories, allowing repositories to be defined and queried.*/
@HasInternalProtocol
public interface RepositoryHandler extends ArtifactRepositoryContainer {/*** Adds a resolver that looks into a number of directories for artifacts. The artifacts are expected to be located in the* root of the specified directories. The resolver ignores any group/organization information specified in the* dependency section of your build script. If you only use this kind of resolver you might specify your* dependencies like <code>":junit:4.4"</code> instead of <code>"junit:junit:4.4"</code>.** The following parameter are accepted as keys for the map:** <table summary="Shows property keys and associated values">* <tr><th>Key</th>*     <th>Description of Associated Value</th></tr>* <tr><td><code>name</code></td>*     <td><em>(optional)</em> The name of the repository.* The default is a Hash value of the rootdir paths. The name is used in the console output,* to point to information related to a particular repository. A name must be unique amongst a repository group.</td></tr>* <tr><td><code>dirs</code></td>*     <td>Specifies a list of rootDirs where to look for dependencies. These are evaluated as per {@link org.gradle.api.Project#files(Object...)}</td></tr>* </table>** <p>Examples:</p>* <pre class='autoTested'>* repositories {*     flatDir name: 'libs', dirs: "$projectDir/libs"*     flatDir dirs: ["$projectDir/libs1", "$projectDir/libs2"]* }* </pre>** @param args The arguments used to configure the repository.* @return the added resolver* @throws org.gradle.api.InvalidUserDataException In the case neither rootDir nor rootDirs is specified of if both* are specified.*/FlatDirectoryArtifactRepository flatDir(Map<String, ?> args);/*** Adds and configures a repository which will look for dependencies in a number of local directories.** @param configureClosure The closure to execute to configure the repository.* @return The repository.*/FlatDirectoryArtifactRepository flatDir(@DelegatesTo(FlatDirectoryArtifactRepository.class) Closure configureClosure);/*** Adds and configures a repository which will look for dependencies in a number of local directories.** @param action The action to execute to configure the repository.* @return The repository.*/FlatDirectoryArtifactRepository flatDir(Action<? super FlatDirectoryArtifactRepository> action);/*** Adds a repository which looks in Gradle Central Plugin Repository for dependencies.** @return The Gradle Central Plugin Repository* @since 4.4*/ArtifactRepository gradlePluginPortal();/*** Adds a repository which looks in Gradle Central Plugin Repository for dependencies.** @param action a configuration action* @return the added resolver* @since 5.4*/ArtifactRepository gradlePluginPortal(Action<? super ArtifactRepository> action);/*** Adds a repository which looks in Bintray's JCenter repository for dependencies.* <p>* The URL used to access this repository is {@literal "https://jcenter.bintray.com/"}.* The behavior of this repository is otherwise the same as those added by {@link #maven(org.gradle.api.Action)}.* <p>* Examples:* <pre class='autoTestedWithDeprecations'>* repositories {*   jcenter {*     artifactUrls = ["http://www.mycompany.com/artifacts1", "http://www.mycompany.com/artifacts2"]*   }*   jcenter {*     name = "nonDefaultName"*     artifactUrls = ["http://www.mycompany.com/artifacts1"]*   }* }* </pre>** @param action a configuration action* @return the added repository* @deprecated JFrog announced JCenter's <a href="https://blog.gradle.org/jcenter-shutdown">sunset</a> in February 2021. Use {@link #mavenCentral()} instead.*/@DeprecatedMavenArtifactRepository jcenter(Action<? super MavenArtifactRepository> action);/*** Adds a repository which looks in Bintray's JCenter repository for dependencies.* <p>* The URL used to access this repository is {@literal "https://jcenter.bintray.com/"}.* The behavior of this repository is otherwise the same as those added by {@link #maven(org.gradle.api.Action)}.* <p>* Examples:* <pre class='autoTestedWithDeprecations'>* repositories {*     jcenter()* }* </pre>** @return the added resolver* @see #jcenter(Action)* @deprecated JFrog announced JCenter's <a href="https://blog.gradle.org/jcenter-shutdown">sunset</a> in February 2021. Use {@link #mavenCentral()} instead.*/@DeprecatedMavenArtifactRepository jcenter();/*** Adds a repository which looks in the Maven central repository for dependencies. The URL used to access this repository is* {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#MAVEN_CENTRAL_URL}.** <p>The following parameter are accepted as keys for the map:** <table summary="Shows property keys and associated values">* <tr><th>Key</th>*     <th>Description of Associated Value</th></tr>* <tr><td><code>name</code></td>*     <td><em>(optional)</em> The name of the repository. The default is* {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_CENTRAL_REPO_NAME} is used as the name. A name* must be unique amongst a repository group.* </td></tr>* <tr><td><code>artifactUrls</code></td>*     <td>A single jar repository or a collection of jar repositories containing additional artifacts not found in the Maven central repository.* But be aware that the POM must exist in Maven central.* The provided values are evaluated as per {@link org.gradle.api.Project#uri(Object)}.</td></tr>* </table>** <p>Examples:</p>* <pre class='autoTested'>* repositories {*     mavenCentral artifactUrls: ["http://www.mycompany.com/artifacts1", "http://www.mycompany.com/artifacts2"]*     mavenCentral name: "nonDefaultName", artifactUrls: ["http://www.mycompany.com/artifacts1"]* }* </pre>** @param args A list of urls of repositories to look for artifacts only.* @return the added repository*/MavenArtifactRepository mavenCentral(Map<String, ?> args);/*** Adds a repository which looks in the Maven central repository for dependencies. The URL used to access this repository is* {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#MAVEN_CENTRAL_URL}. The name of the repository is* {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_CENTRAL_REPO_NAME}.** <p>Examples:</p>* <pre class='autoTested'>* repositories {*     mavenCentral()* }* </pre>** @return the added resolver* @see #mavenCentral(java.util.Map)*/MavenArtifactRepository mavenCentral();/*** Adds a repository which looks in the Maven central repository for dependencies. The URL used to access this repository is* {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#MAVEN_CENTRAL_URL}. The name of the repository is* {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_CENTRAL_REPO_NAME}.** <p>Examples:</p>* <pre class='autoTested'>* repositories {*     mavenCentral()* }* </pre>** @param action a configuration action* @return the added resolver* @since 5.3*/MavenArtifactRepository mavenCentral(Action<? super MavenArtifactRepository> action);/*** Adds a repository which looks in the local Maven cache for dependencies. The name of the repository is* {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_LOCAL_REPO_NAME}.** <p>Examples:</p>* <pre class='autoTested'>* repositories {*     mavenLocal()* }* </pre>* <p>* The location for the repository is determined as follows (in order of precedence):* </p>* <ol>* <li>The value of system property 'maven.repo.local' if set;</li>* <li>The value of element &lt;localRepository&gt; of <code>~/.m2/settings.xml</code> if this file exists and element is set;</li>* <li>The value of element &lt;localRepository&gt; of <code>$M2_HOME/conf/settings.xml</code> (where <code>$M2_HOME</code> is the value of the environment variable with that name) if this file exists and element is set;</li>* <li>The path <code>~/.m2/repository</code>.</li>* </ol>** @return the added resolver*/MavenArtifactRepository mavenLocal();/*** Adds a repository which looks in the local Maven cache for dependencies. The name of the repository is* {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_LOCAL_REPO_NAME}.** <p>Examples:</p>* <pre class='autoTested'>* repositories {*     mavenLocal()* }* </pre>* <p>* The location for the repository is determined as follows (in order of precedence):* </p>* <ol>* <li>The value of system property 'maven.repo.local' if set;</li>* <li>The value of element &lt;localRepository&gt; of <code>~/.m2/settings.xml</code> if this file exists and element is set;</li>* <li>The value of element &lt;localRepository&gt; of <code>$M2_HOME/conf/settings.xml</code> (where <code>$M2_HOME</code> is the value of the environment variable with that name) if this file exists and element is set;</li>* <li>The path <code>~/.m2/repository</code>.</li>* </ol>** @param action a configuration action* @return the added resolver* @since 5.3*/MavenArtifactRepository mavenLocal(Action<? super MavenArtifactRepository> action);/*** Adds a repository which looks in Google's Maven repository for dependencies.* <p>* The URL used to access this repository is {@literal "https://dl.google.com/dl/android/maven2/"}.* <p>* Examples:* <pre class='autoTested'>* repositories {*     google()* }* </pre>** @return the added resolver* @since 4.0*/MavenArtifactRepository google();/*** Adds a repository which looks in Google's Maven repository for dependencies.* <p>* The URL used to access this repository is {@literal "https://dl.google.com/dl/android/maven2/"}.* <p>* Examples:* <pre class='autoTested'>* repositories {*     google()* }* </pre>** @param action a configuration action* @return the added resolver* @since 5.3*/MavenArtifactRepository google(Action<? super MavenArtifactRepository> action);/*** Adds and configures a Maven repository. Newly created instance of {@code MavenArtifactRepository} is passed as an argument to the closure.** @param closure The closure to use to configure the repository.* @return The added repository.*/MavenArtifactRepository maven(@DelegatesTo(MavenArtifactRepository.class) Closure closure);/*** Adds and configures a Maven repository.** @param action The action to use to configure the repository.* @return The added repository.*/MavenArtifactRepository maven(Action<? super MavenArtifactRepository> action);/*** Adds and configures an Ivy repository. Newly created instance of {@code IvyArtifactRepository} is passed as an argument to the closure.** @param closure The closure to use to configure the repository.* @return The added repository.*/IvyArtifactRepository ivy(@DelegatesTo(IvyArtifactRepository.class) Closure closure);/*** Adds and configures an Ivy repository.** @param action The action to use to configure the repository.* @return The added repository.*/IvyArtifactRepository ivy(Action<? super IvyArtifactRepository> action);/*** Declares exclusive content repositories. Exclusive content repositories are* repositories for which you can declare an inclusive content filter. Artifacts* matching the filter will then only be searched in the repositories which* exclusively match it.** @param action the configuration of the repositories** @since 6.2*/void exclusiveContent(Action<? super ExclusiveContentRepository> action);
}

PluginResolutionStrategy插件解决策略

接下来我们看resolutionStrategy,它传入的是一个PluginResolutionStrategy。Kotlin DSL中有大量Action的用法。

pluginManagement {resolutionStrategy {eachPlugin {if (requested.id.namespace == "com.android.tools.build") {useModule("com.android.tools.build:gradle:7.1.2")}if (requested.id.namespace == "com.google.firebase") {useModule("com.google.firebase:firebase-crashlytics-gradle:2.9.2")}}}
}
package org.gradle.plugin.management;import org.gradle.api.Action;
import org.gradle.internal.HasInternalProtocol;/*** Allows modification of {@link PluginRequest}s before they are resolved.** @since 3.5*/
@HasInternalProtocol
public interface PluginResolutionStrategy {/*** Adds an action that is executed for each plugin that is resolved.* The {@link PluginResolveDetails} parameter contains information about* the plugin that was requested and allows the rule to modify which plugin* will actually be resolved.*/void eachPlugin(Action<? super PluginResolveDetails> rule);}
package org.gradle.plugin.management;import javax.annotation.Nullable;/*** Allows plugin resolution rules to inspect a requested plugin and modify which* target plugin will be used.** @since 3.5*/
public interface PluginResolveDetails {/*** Get the plugin that was requested.*/PluginRequest getRequested();/*** Sets the implementation module to use for this plugin.** @param notation the module to use, supports the same notations as {@link org.gradle.api.artifacts.dsl.DependencyHandler}*/void useModule(Object notation);/*** Sets the version of the plugin to use.** @param version version to use*/void useVersion(@Nullable String version);/*** The target plugin request to use.*/PluginRequest getTarget();}

PluginResolveDetails这个类用来允许插件解析规则检查请求的插件并修改将使用目标插件。

DependencyResolutionManagement依赖解决管理

我们再来看看dependencyResolutionManagement和要传入DependencyResolutionManagement。这个类字面意思就告诉我们用来指定依赖解决管理,简单来说,就是我们项目中的那些implementation依赖的库等,从哪些库里面找。

dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {google()mavenCentral()maven {  setUrl("https://jitpack.io") }}
}

这里简单讲解下RepositoriesMode。

package org.gradle.api.initialization.resolve;import org.gradle.api.Incubating;/*** The repository mode configures how repositories are setup in the build.** @since 6.8*/
@Incubating
public enum RepositoriesMode {/*** If this mode is set, any repository declared on a project will cause* the project to use the repositories declared by the project, ignoring* those declared in settings.** This is the default behavior.*/PREFER_PROJECT,/*** If this mode is set, any repository declared directly in a project,* either directly or via a plugin, will be ignored.*/PREFER_SETTINGS,/*** If this mode is set, any repository declared directly in a project,* either directly or via a plugin, will trigger a build error.*/FAIL_ON_PROJECT_REPOS;
}

PREFER_PROJECT表示,如果设置此模式,项目上声明的任何存储库都会导致项目使用项目声明的存储库,忽略在设置中声明的,简单来说就是项目中的存储库优先使用。这也是默认的模式。如果PREFER_SETTINGS,则正好相反。FAIL_ON_PROJECT_REPOS则表示,强制使用设置中的存储库。建议修改模式为FAIL_ON_PROJECT_REPOS强制全局都使用设置中的存储库,方便管理。无论你使用何种模式,你在dependencyResolutionManagement中配置下就能确保可以使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15566.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DDR5—新手入门学习(一)【1-5】

目录 1、DDR背景 &#xff08;1&#xff09;SDR SDRAM时代 &#xff1a; &#xff08;2&#xff09;DDR SDRAM的创新 &#xff1a; &#xff08;3&#xff09;DDR技术的演进 &#xff1a; &#xff08;4&#xff09;需求推动&#xff1a; 2、了解内存 &#xff08;1&…

go学习笔记-从圣经中抄录的接口值的思考

接口值 接口值&#xff0c;由两个部分组成&#xff0c;一个具体的类型和那个类型的值 下面4个语句中&#xff0c;变量w得到了3个不同的值。&#xff08; 开始和最后的值是相同的&#xff09; var w io.Writer w os.Stdout w new(bytes.Buffer) w nil var w io.Writer var…

Python中的数据类型与函数之美

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、Python中的数据类型初探 代码案例&#xff1a; 二、Python内置函数的魅力 代码案例&a…

我用 Midjourney 的这种风格治愈了强迫症

在 Midjourney 能够实现的各种布局之中&#xff0c;有两种风格因其简洁、有序而独居魅力&#xff0c;它们就是平铺 (Flat Lay) 和 Knolling (Knolling 就是 Knolling, 无法翻译&#x1f923;)。要在现实生活中实现这样的美学效果并不容易&#xff0c;你需要精心挑选各种小物件&…

Mac JDK和SDK环境变量配置

一、Java JDK配置 1.下载并安装Java jdk1.8及以上&#xff0c;这个可以在网上自行搜索下载&#xff0c;这里不在详细描述 2.如果不知道JAVA_HOME的安装路径&#xff0c;可以输入命令查看&#xff1a;/usr/libexec/java_home -V &#xff0c;如图 3.在终端输入命令&#xff1…

算法之堆排序

堆排序是一种基于比较的排序算法&#xff0c;通过构建二叉堆&#xff08;Binary Heap&#xff09;&#xff0c;可以利用堆的性质进行高效的排序。二叉堆是一个完全二叉树&#xff0c;可以有最大堆和最小堆两种形式。在最大堆中&#xff0c;父节点的值总是大于或等于其子节点的值…

UIKit之猜图器Demo

需求 实现猜图器Demo 功能分解&#xff1a; 1>下一题切换功能 2>点击图片后能放大并背景变暗&#xff08;本质是透明度的变化&#xff09;。再次点击则缩小&#xff0c;删除暗色背景。 3> 答案区按钮点击则文字消失&#xff0c;选择区对应文字恢复。 4> 选择区…

springboot项目,@Test写法 @Before @After

某文件示例 package cn.xxx.crm.boss;import cn.xxxx.crm.manager.mq.rabbit.AliyunCredentialsProvider; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; im…

第十九届全国环境友好科技竞赛(绿色创业类)正式启动

近日&#xff0c;第十九届全国环境友好科技竞赛&#xff08;绿色创业类&#xff09;正式拉开帷幕。本次竞赛由清华大学、同济大学、西安建筑科技大学及中国环境科学学会共同主办&#xff0c;旨在通过学科竞赛的方式鼓励全国高校学生积极参与到资源节约型和环境友好型的和谐社会…

探索python字典:遍历与访问的艺术

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、获取字典的键与值 1. 获取字典的键 2. 获取字典的值 二、遍历字典的键值对 1. 使用 …

【全开源】二手车置换平台系统小程序(FastAdmin+ThinkPHP+Uniapp)

二手车置换平台系统 特色功能&#xff1a; 车辆评估&#xff1a;系统提供车辆状况、性能和价值的评估功能&#xff0c;通过拍照、上传图片等方式自动识别车辆信息并给出估价建议&#xff0c;帮助买家和卖家更准确地了解车辆价值。 在线交易&#xff1a;平台提供在线购车、售车…

Idea中flume的Interceptor的编写教程

1.新建-项目-新建项目 注意位置是将来打包文件存放的位置&#xff0c;即我们打包好的文件在这/export/data个目录下寻找 2. 在maven项目中导入依赖 Pom.xml文件中写入 <dependencies> <dependency> <groupId>org.apache.flume</groupId> <artifa…

❤Element的使用element

❤Element的使用 1、input输入框 禁止自动补全和下拉提示 input 输入框在输入后浏览器会记录用户输入的值&#xff0c;在下次输入的时候会将记录的值提示在输入框的下面&#xff0c;当输入框是密码的时候&#xff0c;这样可以看见上次输入的密码&#xff0c;这样用户体验不好…

python使用jsonpath来查找key并赋值

目录 一、引言 二、JsonPath简介 三、Python中的JsonPath库 四、使用JsonPath查找JSON Key 五、使用JsonPath赋值JSON Key 六、高级用法 七、结论 一、引言 在数据驱动的现代应用中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;已成为一种广泛使…

基于大数据的支付风险智能防控技术规范

随着大数据、移动互联、人工智能、生物特征识别等技术的快速发展&#xff0c;支付方式正在发生着巨大而深刻的变革&#xff0c;新技术在丰富支付手段、提高支付效率的同时&#xff0c;带来了新的隐患&#xff0c;也对从业机构的风险防控能力提出了更高的要求。 传统的风控技术…

01-02.Vue的常用指令(二)

01-02.Vue的常用指令&#xff08;二&#xff09; 前言v-model&#xff1a;双向数据绑定v-model举例&#xff1a;实现简易计算器Vue中通过属性绑定为元素设置class 类样式引入方式一&#xff1a;数组写法二&#xff1a;在数组中使用三元表达式写法三&#xff1a;在数组中使用 对…

【全部更新完毕】2024电工杯B题详细思路代码成品文章教学:大学生平衡膳食食谱的优化设计及评价

大学生平衡膳食食谱的优化设计及评价 摘要 大学阶段是学生获取知识和身体发育的关键时期&#xff0c;也是形成良好饮食习惯的重要阶段。然而&#xff0c;当前大学生中存在饮食结构不合理和不良饮食习惯的问题&#xff0c;主要表现为不吃早餐或早餐吃得马虎&#xff0c;经常食用…

宝塔面板修改端口后无法登入

今天通过宝塔面板登录腾讯云主机&#xff0c;看到下面的提醒&#xff0c;顺便点进去随便改了个端口 本以为改端口是很简单事情&#xff0c;结果我改完之后面板立马登不上了&#xff0c;接下来我改了登录地址和端口也不行&#xff0c;我以为是防火墙的问题&#xff0c;增加了防火…

ViT:1 从DETR说起

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提供了大模型领域最新技…