web-dev-qa-db-ja.com

Gradleの実装とAPIの設定

私は依存関係を構築しながら、apiimplementation設定の違いを理解しようとしています。
ドキュメンテーションでは、implementationの方がビルド時間が短いと言っていますが、この コメント を同じような質問で見れば、私は疑問に思いますそれは本当ですか?.
私はgradleのエキスパートではないので、誰かが手助けできることを願っています。 のドキュメント はもう読んだことがありますが、わかりやすい説明が疑問に思いました。

137
Viper Alpha

Gradle compileキーワードは廃止され、依存関係を構成するためにapiおよびimplementationキーワードが採用されました。

apiを使用することは、非推奨のcompileを使用することと同等です。したがって、すべてのcompileapiに置き換えると、すべてが正常に機能します。

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();
        }
    }

MyLibrarybuild.gradledependencies{}api構成を次のように使用するとします。

dependencies {
    api project(':InternalLibrary')
}

コードでMyLibraryを使用するため、アプリのbuild.gradleで次の依存関係を追加します。

dependencies {
    api project(':MyLibrary')
}

api構成(または非推奨のcompile)を使用すると、アプリケーションコードでMyLibraryInternalLibraryの両方にアクセスできます。

// 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構成が導入されました。したがって、implementationapiの代わりにMyLibraryを使用すると、

dependencies {
    implementation project(':InternalLibrary')
}

そして、あなたのアプリのbuild.gradle

dependencies {
    implementation project(':MyLibrary')
}

アプリコードでInternalLibrary.giveMeAString()を呼び出すことはできなくなります。

MyLibraryapiを使用してInternalLibraryをインポートする場合、アプリが問題なくInternalLibrary.giveMeAString()を呼び出すことができることに注意してくださいapiまたはimplementationを使用してアプリにMyLibraryを追加することとは無関係です。

このようなボクシング戦略により、Android Gradleプラグインは、InternalLibraryで何かを編集する場合、MyLibrarynotの再コンパイルのみをトリガーする必要があることを知ることができます。 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パーツのみ)

Google I/O 2017-Gradleビルドを高速化する方法(1 *を参照)

Androidのドキュメント

315
MatPag

apiの依存関係は、 パブリック implementation依存関係として(他のモジュールから見て) 非公開 (このモジュールでのみ見られる).

public/privateの変数やメソッドとは異なり、api/implementationの依存関係はランタイムによって強制されません。これは単にビルド時の最適化であり、依存関係の1つがそのAPIを変更したときにGradleがどのモジュールを再コンパイルする必要があるかを知ることができます。

64
dev.bmax

lib1をライブラリとして使用し、lib1lib2をライブラリとして使用するappモジュールがあるとします。このようなもの:app -> lib1 -> lib2

api lib2lib1を使用するとき、appモジュールでlib2またはapi lib1を使用すると、appimplementation lib1コードを見ることができます。

implementation lib2lib1を使用するとき、しかし、applib2コードを見ることができません

3
Ehsan Mashhadi