web-dev-qa-db-fra.com

Bibliothèque Android: fichier de classe introuvable lorsque "projet d'implémentation" est utilisé pour la dépendance de module d'une bibliothèque

Je travaille dans un projet qui a 3 modules comme indiqué ci-dessous:

Project
|
|-- Common 
|
|-- SDK
|
|-- App

Common est un module de bibliothèque Android dont dépendent tous les autres modules, mais je n'ai pas à le publier nulle part, car il ne contient que du code commun pour les autres modules. SDK est un autre projet de bibliothèque Android qui doit être publié sur notre artefact interne. 

App est un exemple de projet du SDK. Je peux publier l'artefact SDK sans aucun problème, mais lorsque je l'importe dans une application cliente, la compilation échoue car aucune des classes du module Common n'est trouvée.

J'utilise implementation pour les dépendances tierces dont dépend le module SDK (par exemple, implementation 'com.squareup.okhttp3:okhttp:3.11.0' et toutes ces dépendances sont ajoutées avec succès au fichier POM SDK) et la dépendance du module Common par implementation project(path: ':Common').

Dans l'application cliente qui importe la bibliothèque SDK, le compilateur affiche l'erreur suivante.

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

(Foo est une classe du module Common)

Pourquoi, lorsque j'importe la SDK, aucune des classes du module Common n'est trouvée? Ce que j'attends, c'est que le compilateur fusionne les deux modules en un seul. Quelqu'un at-il une idée sur la façon dont je peux résoudre ce problème? 

(Je sais qu'une solution consiste à publier Common sur l'artefact, mais je ne souhaite pas le faire car il s'agit uniquement d'un code interne commun).

4
Diego Palomar

Remplacez implementation project(path: ':Common') par api project(path: ':Common') Vous pouvez vérifier cet article .

2
Aolphn

Ceci est le comportement attendu pour les modules gradle; comme vous l'avez supposé, la seule utilisation prise en charge est la publication de chaque artefact (et la liste des dépendances dans le fichier pom).

Il existe un plugin qui peut faire ce dont vous avez besoin sur https://github.com/adwiv/Android-fat-aar , mais il n’est plus mis à jour de sorte que votre kilométrage puisse varier. Des résultats similaires en mettant à jour vos sourcesSKI SDK pour qu'ils pointent directement vers les sources de module communes et suppriment entièrement la dépendance de gradle. Impossible de trouver un bon lien pour cela, mais cela devrait être possible. Cela supprime toute la gestion intégrée des modules, mais peut mieux correspondre à la façon dont vous utilisez le module.

1
Robert Williams

J'ai eu un problème similaire moi-même. 

Une aide visuelle consiste à utiliser Android Studio sa propre vue de la structure de projet:  enter image description here

Fichier -> Structure du projet

Ensuite, pour votre :app, vous pouvez vérifier quel modules dependencies vous avez:

 enter image description here

Si vous en avez besoin, vous pouvez supprimer les dépendances actuelles du module et les ajouter à nouveau pour vérifier. Ensuite, lorsque vous cliquez sur "OK", Gradle essaiera de synchroniser ses fichiers.

De cette façon, vous laissez Android Studio faire le travail d'intégration de tous les modules et, espérons-le, cela réglera votre problème.


PS: Je pense que vous importez votre projet de la mauvaise façon. Vous devriez utiliser api au lieu de implementation. De la documentation:

api: Lorsqu'un module inclut une dépendance api, il laisse Gradle sachez que le module veut exporter cette dépendance de manière transitoire vers d’autres modules, de sorte qu’il soit disponible à la fois pour l’exécution et pour temps de compilation. Cette configuration se comporte exactement comme la compilation (qui est maintenant obsolète .__), et vous devriez généralement l’utiliser uniquement dans la bibliothèque modules. En effet, si une dépendance d'api change de son externe API, Gradle recompile tous les modules ayant accès à cette dépendance au moment de la compilation. Donc, avoir un grand nombre de dépendances d'api peut augmenter considérablement les temps de construction. Sauf si vous voulez exposer un L'API de dépendance à un module de test séparé, les modules d'application devraient plutôt utiliser des dépendances d'implémentation.

Consultez les documents officiels: https://developer.Android.com/studio/build/gradle-plugin-3-0-0-migration.html#new_configurations

0
André Sousa