私は依存関係を構築しながら、api
とimplementation
設定の違いを理解しようとしています。
ドキュメンテーションでは、implementation
の方がビルド時間が短いと言っていますが、この コメント を同じような質問で見れば、私は疑問に思いますそれは本当ですか?.
私はgradleのエキスパートではないので、誰かが手助けできることを願っています。 のドキュメント はもう読んだことがありますが、わかりやすい説明が疑問に思いました。
Gradle compile
キーワードは廃止され、依存関係を構成するためにapi
およびimplementation
キーワードが採用されました。
api
を使用することは、非推奨のcompile
を使用することと同等です。したがって、すべてのcompile
をapi
に置き換えると、すべてが正常に機能します。
implementation
キーワードを理解するには、次の例を検討してください。
例
MyLibrary
という別のライブラリを内部で使用するInternalLibrary
というライブラリがあるとします。このようなもの:
// 'InternalLibrary' module
public class InternalLibrary {
public static String giveMeAString(){
return "hello";
}
}
// 'MyLibrary' module
public class MyLibrary {
public String myString(){
return InternalLibrary.giveMeAString();
}
}
MyLibrary
build.gradle
がdependencies{}
のapi
構成を次のように使用するとします。
dependencies {
api project(':InternalLibrary')
}
コードでMyLibrary
を使用するため、アプリのbuild.gradle
で次の依存関係を追加します。
dependencies {
api project(':MyLibrary')
}
api
構成(または非推奨のcompile
)を使用すると、アプリケーションコードでMyLibrary
とInternalLibrary
の両方にアクセスできます。
// Access 'MyLibrary' (as desired and expected)
MyLibrary myLib = new MyLibrary();
System.out.println(myLib.myString());
// Can ALSO access the internal library too (and you shouldn't)
System.out.println(InternalLibrary.giveMeAString());
このように、モジュールMyLibrary
は潜在的に何かの内部実装を「漏らしている」。直接インポートされないため、使用しないでください(使用できません)。
これを防ぐためにimplementation
構成が導入されました。したがって、implementation
でapi
の代わりにMyLibrary
を使用すると、
dependencies {
implementation project(':InternalLibrary')
}
そして、あなたのアプリのbuild.gradle
:
dependencies {
implementation project(':MyLibrary')
}
アプリコードでInternalLibrary.giveMeAString()
を呼び出すことはできなくなります。
MyLibrary
がapi
を使用してInternalLibrary
をインポートする場合、アプリはが問題なくInternalLibrary.giveMeAString()
を呼び出すことができることに注意してくださいapi
またはimplementation
を使用してアプリにMyLibrary
を追加することとは無関係です。
このようなボクシング戦略により、Android Gradleプラグインは、InternalLibrary
で何かを編集する場合、MyLibrary
とnotの再コンパイルのみをトリガーする必要があることを知ることができます。 InternalLibrary
へのアクセス権がないため、アプリ全体の再コンパイル。
ネストされた依存関係が多数ある場合、このメカニズムによりビルドを大幅に高速化できます。 (これを完全に理解するには、最後にリンクされているビデオをご覧ください)
結論
新しいAndroid Gradleプラグイン3.X.Xに切り替える場合は、compile
をすべてimplementation
キーワード(1 *)に置き換える必要があります。次に、アプリのコンパイルとテストを試みます。問題がなければコードをそのままにして、依存関係に問題があるか、プライベートでアクセスしにくいものを使用した可能性があります。 Android GradleプラグインエンジニアJerome Dochezによる提案(1)*)
ライブラリの管理者である場合は、ライブラリのパブリックAPIに必要なすべての依存関係にapi
を使用し、テストの依存関係または最終ユーザーが使用してはならない依存関係にはimplementation
を使用する必要があります.
役に立つ記事実装とapiの違いを紹介する
リファレンス(これは、時間を節約するために分割された同じビデオです)
Google I/O 2017-Gradleビルドを高速化する方法(フルビデオ)
Google I/O 2017-Gradleビルドの速度を上げる方法(新しいGRADLE PLUGIN 3.0.0パーツのみ)
api
の依存関係は、 パブリック implementation
依存関係として(他のモジュールから見て) 非公開 (このモジュールでのみ見られる).
public
/private
の変数やメソッドとは異なり、api
/implementation
の依存関係はランタイムによって強制されません。これは単にビルド時の最適化であり、依存関係の1つがそのAPIを変更したときにGradle
がどのモジュールを再コンパイルする必要があるかを知ることができます。
lib1
をライブラリとして使用し、lib1
がlib2
をライブラリとして使用するapp
モジュールがあるとします。このようなもの:app -> lib1 -> lib2
。
api lib2
でlib1
を使用するとき、app
モジュールでlib2
またはapi lib1
を使用すると、app
はimplementation lib1
コードを見ることができます。
implementation lib2
でlib1
を使用するとき、しかし、app
はlib2
コードを見ることができません。