Ressourcengenerierung in Android-Projekten – RegisterGeneratedResFolder

Feb 12 2023
In der Android-Welt sind die Konzepte der Code- und Ressourcengenerierung sehr bekannt. Die Codegenerierung wird in den meisten Projekten verwendet und ist die Kernmechanik hinter Dagger, Room und anderen Bibliotheken. Aber was ist mit den Ressourcen? Beispielsweise während des Build-Prozesses Ihre Google-Dienste.

In der Android-Welt sind die Konzepte der Code- und Ressourcengenerierung sehr bekannt. Die Codegenerierung wird in den meisten Projekten verwendet und ist die Kernmechanik hinter Dagger, Room und anderen Bibliotheken. Aber was ist mit den Ressourcen? Während des Erstellungsprozesses google-services.jsonwird Ihre Datei beispielsweise analysiert und in eine values.xmlDatei im generatedOrdner umgewandelt, die von Firebase-Bibliotheken verwendet werden soll. Wie sich herausstellt, ist das Erstellen und Verwenden Ihrer eigenen generierten Ressourcen einfach, solange Sie wissen, was Sie mit ihnen machen sollen, sobald Sie sie haben. Es scheint ziemlich einfach zu sein: Sie erstellen die benötigten Dateien und legen sie im generierten Ordner ab. Es erfordert jedoch etwas mehr Arbeit.

Gradle-Aufgabe zur String-Konvertierung

Lassen Sie uns eine einfache Gradle-Aufgabe erstellen, die eine JSON-Datei mit einigen Zeichenfolgen in eine XML-Datei mit Android-Zeichenfolgen konvertiert und das Ergebnis in einem generatedOrdner speichert. Den anderen Dateien in diesem Verzeichnis nach zu urteilen, sollte der Pfad wie folgt lauten:

app/build/generated/res/${generator}/${sourceSet}/values/strings.xml

Das sollte reichen, oder? Wenn Sie versuchen, die App mithilfe von Ressourcen aus der generierten Datei zu erstellen, wird dies nicht funktionieren. Weder Android Studio noch Gradle können Ihre Datei als Teil des Projekts erkennen. Es gibt eine Möglichkeit, sie dazu zu bringen.

RegisterGeneratedResFolderzur Rettung

Es gibt eine magische Methode in der BaseVariantBenutzeroberfläche des Android-Build-Systems, registerGeneratedResFolderdie genau das tut.

Es erfordert ein FileCollectionObjekt, das auf unseren Ordner verweist und die Aufgabe angibt, die ihn generiert.

Der obige Kommentar sagt uns, dass die Aufgabe von Gradle in den Build-Prozess eingebunden wird, wir müssen also nur den Ordner registrieren. Hierbei ist zu beachten, dass der dafür verwendete Pfad ein anderer ist als der Pfad, in dem die generierte Datei tatsächlich gespeichert wird.

app/build/generated/res/${generator}/${sourceSet}

generateStringsFileDie Aufgabe wird vor ausgeführt mergeResources, wodurch alle neuen Ressourcen für die nächsten Build-Phasen und in Android Studio verfügbar sind. Sie können es auch manuell ausführen, um die benötigten Dateien zu erstellen, sodass während der Arbeit keine „Ressource nicht gefunden“-Fehler auftreten.

Was kommt als nächstes?

Während das obige Beispiel für einfache Fälle ausreicht, hat es einen großen Nachteil: Die Aufgabe ist nicht inkrementell. Mit anderen Worten: Es wird jedes Mal ausgeführt, wenn das Projekt erstellt wird, was unweigerlich die Erstellungszeit verlängert. Außerdem gibt es derzeit keine Möglichkeit, Dateien anzugeben, die als Eingabe verwendet werden müssen, und den Ordner zum Speichern des Ergebnisses anzugeben. Wir können das erste Problem lösen, indem wir die Aufgabe selbst inkrementell machen. Das zweite Problem wird gelöst, indem Aufgabeneingaben hinzugefügt und möglicherweise in ein Plugin verpackt werden. Das Erstellen eines benutzerdefinierten Plugins würde den Rahmen dieses Artikels sprengen, aber Sie können den Code in meinem GitHub-Repo finden .

Dies war mein erster tiefer Einblick in Gradle und das Android-Build-System und ich hoffe, dass es Ihnen dabei hilft, Ihre eigenen Herausforderungen zu meistern. Viel Spaß beim Codieren!