Abhängigkeitsmanagement in einem Multi-Modul-Projekt auf Hagel

Bild

Eintrag


Der Artikel wurde mit Blick auf native Android-Projekte geschrieben. Da der Gradle jedoch ein universelles Montagesystem ist, eignet er sich im Prinzip für andere Projekte, die der Gradle sammeln kann. Die Idee ist nicht meine, ich habe sie aus dem Github-Projekt von Jake Wharton SdkSearch übernommen - einer Reihe von Programmen zum Durchsuchen der Dokumentation nach Android SDK.

Das Problem


Eine moderne Anwendung ist ohne Verwendung von Bibliotheken kaum (unpraktisch) zu schreiben. Mit dem Aufkommen von Abhängigkeiten entsteht die Aufgabe, die Versionierung zu verwalten. Vielleicht ist dies für eine Einzelmodul-Android-Anwendung der mittleren Hand kein Problem, dann ist das Problem in größeren Projekten mit Code-Wiederverwendung relevant. Insbesondere bei der Versionskontrolle von AndroidX- Unterstützungsbibliotheken, für die die Versionierung einfach nicht zumutbar ist, sehen Sie sich nur AndroidX-Versionen an

Lösung


Bei so vielen Abhängigkeiten ist es sehr wichtig, dass alle Module von einer Version der Bibliothek abhängen, da sonst Überraschungen in der Laufzeit an der unerwartetsten Stelle auftreten.
Gradle verwendet groovy als Skriptsprache, die zusammen mit der dynamischen Eingabe eine bequeme Möglichkeit zum Organisieren des Abhängigkeitsmanagements bietet.

Im DSL-Grad können Sie dem Projekt mithilfe des ext ExtraPropertiesExtension-Objekts Eigenschaften hinzufügen. Innerhalb des Modulskripts können Sie auch auf das Projektskript (Root-Modul) zugreifen, mit dem Sie alle Versionen der Abhängigkeiten im Root-Skript deklarieren können, und Sie können bereits von jedem Modul darin auf sie verweisen.

Lassen Sie unsere Android-Anwendung beispielsweise die Abhängigkeiten verwenden: Kotlin, Kotlin Stdlib, Kotlin Junit, Facebook SDK, AndroidX, Google Material

Root build.gradle:

buildscript { ext { versions = [ 'kotlin': '1.3.50', 'fb': '4.40.0' ] deps = [ 'kotlin': [ 'stdlib': [ 'jdk': "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}" ], 'test': [ 'common': "org.jetbrains.kotlin:kotlin-test-common:${versions.kotlin}", 'annotations': "org.jetbrains.kotlin:kotlin-test-annotations-common:${versions.kotlin}", 'jdk': "org.jetbrains.kotlin:kotlin-test-junit:${versions.kotlin}" ] ], 'androidx' : [ 'annotation': "androidx.annotation:annotation:1.1.0", 'appCompat': 'androidx.appcompat:appcompat:1.1.0', 'constraintLayout': 'androidx.constraintlayout:constraintlayout:1.1.3', 'ktx': 'androidx.core:core-ktx:1.1.0', 'dynamicAnimation': 'androidx.dynamicanimation:dynamicanimation:1.0.0', 'gridLayout': 'androidx.gridlayout:gridlayout:1.0.0', 'localBroadcastManager': 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0', 'multidex': 'androidx.multidex:multidex:2.0.1', 'recyclerView': 'androidx.recyclerview:recyclerview:1.1.0-beta04' ], 'material': 'com.google.android.material:material:1.0.0', 'fb': [ 'core': "com.facebook.android:facebook-core:${versions.fb}", 'login': "com.facebook.android:facebook-login:${versions.fb}", 'share': "com.facebook.android:facebook-share:${versions.fb}" ] ] repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.6.0-alpha11' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}" } } 

Ein paar Punkte:
Wenn mehrere Abhängigkeiten eine Version haben, z. B. Teile eines großen SDK, wird die Version zur Versionseigenschaft hinzugefügt, z. B. bei Versionen von Kotlin und Facebook. Wenn die Abhängigkeit in Form einer einzelnen Zeile vorliegt, z. B. bei Google-Material, ist es nicht praktisch, eine Version zu erstellen. Versionen von AndroidX-Bibliotheken müssen auch nicht herausgenommen werden, weil Google lehnte es ab, Versionen miteinander auszurichten, um die Veröffentlichung einzelner Bibliotheken zu beschleunigen.

Aufgrund dieser Definition wird die Deklaration von Abhängigkeiten in allen untergeordneten Modulen zu einer prägnanten Hierarchie, die frei von Versionsverwaltung ist, weil Jetzt hängen alle Module von denselben Bibliotheksversionen ab.

Beispiel für den Abschnitt Modulabhängigkeiten in build.gradle

 dependencies { implementation deps.kotlin.stdlib.jdk implementation deps.androidx.appCompat implementation deps.androidx.browser implementation deps.androidx.cardView implementation deps.androidx.constraintLayout implementation deps.androidx.ktx implementation deps.androidx.multidex implementation deps.androidx.recyclerView implementation deps.material implementation deps.fb.core implementation deps.fb.login implementation deps.fb.share testImplementation deps.kotlin.test.jdk } 

Was geschah - die Bibliotheksversionen der Module verschwanden, eine Hierarchie von Bibliotheken erschien
Es ist auch erwähnenswert, dass das Modul nicht von allen im Stammskript beschriebenen Bibliotheken abhängen muss, sondern nur von denen, die erforderlich sind.

Wie ich oben erwähnt habe, ist hier ein Arbeitsentwurf, der ein solches Schema verwendet.

Source: https://habr.com/ru/post/de468959/


All Articles