Gradle 实现与 API 配置 [英] Gradle Implementation vs API configuration

查看:20
本文介绍了Gradle 实现与 API 配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在构建我的依赖项时找出 apiimplementation 配置之间的区别.
在文档中,它说 implementation 有更好的构建时间,但是,看到这个评论 在一个类似的问题中,我想知道这是不是真的.
由于我不是 Gradle 的专家,我希望有人可以提供帮助.我已经阅读了文档,但我想知道一个易于-理解解释.

解决方案

Gradle compile 关键字被弃用,取而代之的是 apiimplementation配置依赖项的关键字.

使用api相当于使用不推荐使用的compile,所以如果你用api替换所有的compile一切都会照常进行.

要理解 implementation 关键字,请考虑以下示例.

示例

假设您有一个名为 MyLibrary 的库,它在内部使用另一个名为 InternalLibrary 的库.像这样:

//'InternalLibrary' 模块公共类内部图书馆{公共静态字符串 giveMeAString(){返回你好";}}

//'MyLibrary' 模块公共类 MyLibrary {公共字符串 myString(){返回 InternalLibrary.giveMeAString();}}

假设 MyLibrary build.gradledependencies{} 中使用 api 配置,如下所示:

依赖项{api 项目(':InternalLibrary')}

您想在代码中使用 MyLibrary,因此在应用程序的 build.gradle 中添加此依赖项:

依赖项{实施项目(':MyLibrary')}

使用 api 配置(或已弃用的 compile),您可以在应用程序代码中访问 InternalLibrary:

//访问MyLibrary"(授予)MyLibrary myLib = new MyLibrary();System.out.println(myLib.myString());//也可以访问内部库(但你不应该)System.out.println(InternalLibrary.giveMeAString());

通过这种方式,MyLibrary 模块可能会泄漏"某事的内部实现.您不应该(能够)使用它,因为它不是由您直接导入的.

引入了 implementation 配置来防止这种情况.所以现在如果你在 MyLibrary 中使用 implementation 而不是 api :

依赖项{实施项目(':InternalLibrary')}

您将无法再在应用代码中调用 InternalLibrary.giveMeAString().

这种装箱策略让Android Gradle插件知道如果你在InternalLibrary中编辑了一些东西,它必须只触发MyLibrary的重新编译,不会 重新编译整个应用程序,因为您无权访问 InternalLibrary.

当您有很多嵌套依赖项时,此机制可以大大加快构建速度.(观看最后链接的视频以全面了解这一点)

结论

  • 当您切换到新的 Android Gradle 插件 3.XX 时,您应该将所有 compile 替换为 implementation 关键字 *(1)<强>.然后尝试编译和测试您的应用程序.如果一切正常,就让代码保持原样,如果您遇到问题,您的依赖项可能有问题,或者您使用了现在私有且无法访问的东西.*Android Gradle 插件工程师 Jerome Dochez 的建议 (1))

  • 如果您是库管理员,您应该对库的公共 API 所需的每个依赖项使用 api,而对测试依赖项使用 implementation或最终用户不得使用的依赖项.

实用文章实现api

参考资料(这是为了节省时间而拆分的同一视频)

Google I/O 2017 - 如何加速 Gradle 构建(完整视频)

Google I/O 2017 - 如何加速 Gradle 构建(仅限新 GRADLE 插件 3.0.0 部分))

Google I/O 2017 - 如何加速 Gradle 构建(参考 1*)

Android 文档

I'm trying to figure out what is the difference between api and implementation configuration while building my dependencies.
In the documentation, it says that implementation has better build time, but, seeing this comment in a similar question I got to wonder if is it true.
Since I'm no expert in Gradle, I hope someone can help. I've read the documentation already but I was wondering about an easy-to-understand explanation.

解决方案

Gradle compile keyword was deprecated in favor of the api and implementation keywords to configure dependencies.

Using api is the equivalent of using the deprecated compile, so if you replace all compile with api everything will works as always.

To understand the implementation keyword consider the following example.

EXAMPLE

Suppose you have a library called MyLibrary that internally uses another library called InternalLibrary. Something like this:

// 'InternalLibrary' module
public class InternalLibrary {
    public static String giveMeAString(){
        return "hello";
    }
}

// 'MyLibrary' module
public class MyLibrary {
    public String myString(){
        return InternalLibrary.giveMeAString();
    }
}

Suppose the MyLibrary build.gradle uses api configuration in dependencies{} like this:

dependencies {
    api project(':InternalLibrary')
}

You want to use MyLibrary in your code so in your app's build.gradle you add this dependency:

dependencies {
    implementation project(':MyLibrary')
}

Using the api configuration (or deprecated compile) you can access InternalLibrary in your application code:

// Access 'MyLibrary' (granted)
MyLibrary myLib = new MyLibrary();
System.out.println(myLib.myString());

// Can ALSO access the internal library too (but you shouldn't)
System.out.println(InternalLibrary.giveMeAString());

In this way the module MyLibrary is potentially "leaking" the internal implementation of something. You shouldn't (be able to) use that because it's not directly imported by you.

The implementation configuration was introduced to prevent this. So now if you use implementation instead of api in MyLibrary:

dependencies {
    implementation project(':InternalLibrary')
}

you won't be able to call InternalLibrary.giveMeAString() in your app code anymore.

This sort of boxing strategy allows Android Gradle plugin to know that if you edit something in InternalLibrary, it must only trigger the recompilation of MyLibrary and not the recompilation of your entire app, because you don't have access to InternalLibrary.

When you have a lot of nested dependencies this mechanism can speed up the build a lot. (Watch the video linked at the end for a full understanding of this)

CONCLUSIONS

  • When you switch to the new Android Gradle plugin 3.X.X, you should replace all your compile with the implementation keyword *(1). Then try to compile and test your app. If everything it's ok leave the code as is, if you have problems you probably have something wrong with your dependencies or you used something that now is private and not more accessible. *Suggestion by Android Gradle plugin engineer Jerome Dochez (1))

  • If you are a library mantainer you should use api for every dependency which is needed for the public API of your library, while use implementation for test dependencies or dependencies which must not be used by the final users.

Useful article Showcasing the difference between implementation and api

REFERENCES (This is the same video splitted up for time saving)

Google I/O 2017 - How speed up Gradle builds (FULL VIDEO)

Google I/O 2017 - How speed up Gradle builds (NEW GRADLE PLUGIN 3.0.0 PART ONLY)

Google I/O 2017 - How speed up Gradle builds (reference to 1*)

Android documentation

这篇关于Gradle 实现与 API 配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆