When developing Android applications, there are times when certain parts of the code can be taken out as libraries so that you can reuse them in different projects:
Most often, all problems were solved long before us, but in our case it was necessary to take out part of the business logic layer and virtually the entire layer responsible for the data in our 3 main products of the combined company Roof Roof Market . All our products are classified as vehicles, real estate and other goods. Therefore, we, the developers, decided to write one solution for all products of the company. In addition, it facilitated our work.
The easiest solution is to use git submodule. If you briefly explain his work, then to git repository you attach a link to another git repository, which should automatically be cloned with the parent. It would seem simple: we have several git repository, where all our modular libraries are stored and you just need to specify it in the git submodule.
But what about the versions? When updating via the git submodule update command, the changes in the submodule are erased, merge does not occur. You will have to be constantly updated when another developer makes a change in this submodule. Instead, it’s worth developing modules as libraries with a jar file or Android Archive (aar). In fact, these archives contain the same files that could be in the git submodule, but now there is a more understandable versioning instead of a commit or tag history.
When publishing libraries, it’s worth considering that they should not contain confidential company data. Moreover, it will not be convenient for other developers if the library contains code relating to a specific company. Therefore, we need a private artifactory for storing libraries in the closed access. There are many open source solutions, but we use JFrog Artifactory .
And if you can publish? In this case, you will find a bright road to the world of open source projects. Simply find open web servers that support gradle so that hosted jar and aar files are pulled through dependency in your projects.
It all starts easy - go to File > New > New Module…
The name of the library that you specify in this window will become the name of your library's binaries.
Having created a module, you can start writing code. If you write tests with the attached code, the rest of the team will understand how to use your module. Even better, create a new sample app module that works exclusively with your module for demonstration on real devices. It is more convenient when you need to pre-test the code before publishing to an artifactory. To do this, simply specify the dependency in build.gradle . In the examples, I will specify librarymodule as the name of the module.
# {module project}/sample-app dependencies { implementation project(":librarymodule") }
Take the build script from Chris Banes: Gradle script to load artifacts in Maven repositories
Specifically, in his case, the process is described in the maven repository for public publication. The basic settings are absolutely identical: in each module that needs to be published, we call the gradle script file from the module's build.gradle file and create gradle.properties, where the configuration information for the publication will lie. We are interested in the ability to publish in a private artifactory
# {project}/build.gradle RELEASE_REPOSITORY_URL={artifactory_url}/release-modules SNAPSHOT_REPOSITORY_URL={artifactory_url}/snapshot-modules
We need to add 2 folders for publication in the artifactory: one for the official release and a snapshot for the test builds of the modules.
When we have finally configured the configuration file gradle.properties, we are ready to make the first publication of the libraries in the artifactory. In the test build, we specify SNAPSHOT in VERSION_NAME. Then execute the command:
./gradlew clean build sdk:uploadArchives
We managed to manually publish the modules in our private artifactory. At the end, it remains to configure the CI environment so that we can embed the publication into our development process.
We want only CI to publish in release artifactory, and for the rest we will add free read and write access to the snapshot. Therefore, we will make changes in the root file gradle.properties, which usually lies in ~/.gradle/gradle.properties
. We assign {% username%} and {% password%} for access when publishing to the artifactory. This way, we will have the access level set up without making changes to .gitignore.
// ~/.gradle/gradle.properties artifactory_username=login artifactory_password=password
Add a trigger to the master branch so that when merge we have an assembly assembled for publication in a release artifactory. We add test launches to the build task list if we have them in the module. It will be good to adjust the auto increment version.
# Checkout git repository with modules # ./gradlew test # ./gradlew librarymodule:build # artifactory ./gradlew libarrymodule:uploadArchives
As soon as CI assembles the assembly and floods it into an artifactory, a dependency of this module can be added to the project. But hey, we also need to add a url to our artifactory, because they are not available in a typical repository like maven
# {project}/build.gradle allprojects { repositories { maven { url artifactory_url/release-modules } maven { url {artifactory_url}/snapshot-modules } } }
Now we can use it in the project.
# {project}/app/build.gradle dependencies { implementation 'kz.kolesa-team: librarymodule:1.0.0' }
When Kotlin is connected to our modules, the documentation for Kotlin files is not pulled up. It turned out that for this you need to add a gradle task with Dokka .
If several developers specified identical versions for libraries when publishing, then, naturally, the latest version of the model was provided with the latest version. During the development process, the module was required to specify a postfix with the ticket identifier from Jira. It turns out something like 1.0.1-AAS-1-SNAPSHOT
.
Over time, we have increased the number of modules. We kept each module in a separate git repository. A lot of git repository creates a large amount of inconvenience in the development process if a module is dependent on other modules. In the end, it turned out that to perform a single task, it was necessary to create a PR in each git repository. It is not entirely clear in what order they should be tested, not taking into account the permanent change in PR, if changes were made in one of the PRs. Therefore, to use one git repository for all modules in practice turned out to be the most convenient.
You may have many such modules. If a particular module is not required in a particular project, then we can easily remove the dependency, which ultimately allows us not to write duplicate codes in each of three of our projects.
This modular development of the internal components of the business will help us increase the speed of delivery of features to users. In conclusion, it is worth noting the important advantage of modular development - the assembly of apk files will take much less time, since gradle will reassemble only the part of the module in which the change occurred.
Source: https://habr.com/ru/post/353942/
All Articles