web-dev-qa-db-ja.com

Androidライブラリ:ライブラリのモジュール依存関係に「実装プロジェクト」が使用されている場合、クラスファイルが見つかりません

以下に示すように、3つのモジュールを持つプロジェクトで作業しています。

_Project
|
|-- Common 
|
|-- SDK
|
|-- App
_

CommonはAndroid他のすべてのモジュールが依存するライブラリモジュールですが、他のモジュールの共通コードしか含まれていないため、どこにも公開する必要はありません。他のモジュールではhand SDKは、別のAndroidライブラリプロジェクトであり、内部のアーティファクトで公開する必要があります。

AppはSDKのサンプルプロジェクトです。 SDKアーティファクトを問題なく公開できますが、クライアントアプリケーションにインポートすると、Commonモジュールのクラスが見つからないため、コンパイルが失敗します。

SDKモジュールが依存するサードパーティの依存関係については、implementationを使用します(たとえば、_implementation 'com.squareup.okhttp3:okhttp:3.11.0'_とそれらの依存関係はすべてSDK POMファイルに正常に追加されます)。 Commonモジュールimplementation project(path: ':Common')を使用しています。

SDKライブラリをインポートするクライアントアプリケーションで、コンパイラは次のエラーを表示します

_Error: cannot access Foo
class file for com.acme.Foo not found
_

(FooはCommonモジュールのクラスです)

SDKをインポートするときに、Commonモジュールのクラスが見つからないのはなぜですか?私が期待しているのは、コンパイラが2つのモジュールを1つのモジュールにマージすることです。この問題をどのように解決できるかについて誰かが考えていますか?

(解決策はアーティファクトにCommonを公開することですが、これは内部共通コードにすぎないため、実行したくありません)。

9
Diego Palomar

私自身も同様の問題がありました。

視覚的なヘルプはAndroid Studio独自のプロジェクト構造ビュー: enter image description here

ファイル->プロジェクト構造

次に、:app確認できますmodules dependencies あなたが持っている:

enter image description here

必要に応じて、現在のモジュールの依存関係を削除し、再度確認するために再度追加できます。その後、「OK」をクリックすると、gradleはそのファイルを同期しようとします。

このようにして、Android Studioにすべてのモジュールを統合する作業を行わせることができます。うまくいけば、問題が修正されます。


PS:プロジェクトを間違った方法でインポートしていると思います。 apiの代わりにimplementationを使用する必要があります。ドキュメントから:

api:モジュールにapi依存関係が含まれている場合、モジュールがその依存関係を他のモジュールに推移的にエクスポートすることをGradleに知らせ、実行時とコンパイル時の両方でそれらを使用します。この構成はコンパイル(現在は非推奨)と同じように動作し、通常はライブラリモジュールでのみ使用する必要があります。これは、API依存関係が外部APIを変更すると、Gradleはコンパイル時にその依存関係にアクセスできるすべてのモジュールを再コンパイルするためです。そのため、多数のAPI依存関係があると、ビルド時間が大幅に増加する可能性があります。依存関係のAPIを別のテストモジュールに公開する場合を除き、アプリモジュールは代わりに実装の依存関係を使用する必要があります。

公式ドキュメントを確認してください: https://developer.Android.com/studio/build/gradle-plugin-3-0-0-migration.html#new_configurations

3
André Sousa

implementation project(path: ':Common')api project(path: ':Common')に置き換えます。APIと実装の違いについては、確認できます この記事

3
Aolphn

これは、gradleモジュールの予想される動作です。ご想像のとおり、サポートされる使用法は、それぞれを個別のアーティファクトとして公開すること(およびpomファイルに依存関係をリストすること)のみです。

https://github.com/adwiv/Android-fat-aar に必要なことを行うプラグインがありますが、メンテナンスされていないため、走行距離が異なる場合があります。または、共通のモジュールソースを直接指すようにSDK sourceSetsを更新し、gradleの依存関係を完全に削除することで、同様の結果を得ることができます。このための適切なリンクが見つかりませんが、可能なはずです。これにより、組み込みのモジュール処理がすべて削除されますが、モジュールの使用方法と一致する場合があります。

1
Robert Williams

AndréSousaから最も投票された回答は正しいですが、ライブラリの依存関係を直接使用しない場合にのみ役立ちます。

いくつかの一般的なライブラリ(Joda DateTime、firebaseなど)をインポートする可能性のある「Common」モジュールがあるのは一般的なケースです。その場合、ライブラリ内のそのような依存関係はすべて、「実装」ではなく「api」で宣言する必要がありますです。これにより、アプリがCommonモジュールをインポートするときに、これらのクラスも使用できるようになります。

1
vanomart

私は同じ問題に直面しました。

私の場合、kotlinライブラリを作成し、Javaプロジェクトで追加しようとしました。ライブラリにkotlinが設定されていることを確認してください。

これでうまくいきました。

0
Ankur Yadav