background

In normal development, some independent functional modules will be extracted as SDK, which not only facilitates business access, but also enables rapid reuse of other business lines. Then we need to package the SDK and upload it to the Maven repository for the business side to rely on.

First, the compiled product

We need to know what the artifact is before we upload it to the Maven repository.

The Android Gradle plugin will generate different types of plug-ins according to the project Gradle application.

1.1 the APK component

The gradle configuration file of the Android main project app depends on:

apply plugin: 'com.android.application'
Copy the code

Therefore, after compiling the commands./gradlew assembleDebug or./gradlew assembleRelease, the output is generated in build/outputs/ APK:

As shown, APK is the product (component).

1.2 Android App Bundle (AAB) Components

For overseas markets, Google Play apps must be packaged in aAB instead of APK. The compiling commands are./gradlew bundleDebug or./gradlew bundleRelease. Products for:

1.3 the AAR artifacts

A typical Module, when compiled and packaged, generates an AAR:

Publish plugin

Once we have the artifacts, we need to upload them to a Maven repository (usually a private repository) that companies can rely on directly. The publish plugin is used for uploading. Maven-publish is a maven-publish plugin that was used before APG 3.6.0.

2.1 Maven-publish plug-in

We can create a new gradle file, such as maven_publish.gradle. Specifically for uploading the AAR. The configuration is as follows:

Maven-publish {// Creates a list of things that maven-publish Creates  Maven publication called "myPublication". myPublication(MavenPublication) { groupId 'com.sdk.aarpub' artifactId 'aAR-test' version '1.2.2' // Your package version // artifact publishArtifact //Example: *. / target/myJavaClasses. Jar * an artifact "build/outputs/aar/aar - test - the aar" / / aar package directory / / take dependence, Node.withxml {def dependenciesNode = asNode(). AppendNode ('dependencies') def dependency = [configurations.compile] if (configurations.hasProperty("api")) { scopes.add(configurations.api) } if (configurations.hasProperty("implementation"))  { scopes.add(configurations.implementation) } if (configurations.hasProperty("debugImplementation")) { scopes.add(configurations.debugImplementation) } if (configurations.hasProperty("releaseImplementation")) { scopes.add(configurations.releaseImplementation) } // if (project.ext.targetType ! = "jar") { // scopes.add(configurations.provided) // } scopes.each { scope -> scope.allDependencies.each { if (it instanceof ModuleDependency) { boolean isTransitive = ((ModuleDependency) it).transitive if (! isTransitive) { println "<<<< not transitive dependency: [${it.group}, ${it.name}, ${it.version}]" return } } if (it.group == "${project.rootProject.name}.libs" || it.version == 'unspecified') { return }  if (it.group && it.name && it.version) { def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', it.group) dependencyNode.appendNode('artifactId', it.name) dependencyNode.appendNode('version', it.version) dependencyNode.appendNode('scope', Scope.name)}}}}}} // Repositories *to* which Gradle can publish artifacts Repositories {maven {// Upload to the project local repository URL uri('.. /local_mavenrepo') // credentials { // username "default" // password "default" // } } } } }Copy the code

After assemble, publish:

./gradlew publish
Copy the code

2.2 Using Maven plug-ins

Old way:

Plugins {mavenDeployer{repository(URL: uri('.. GroupId = 'com.sdk.aarpub' pom.artifactid = 'aAR-test' pom.version = '1.1.0' //mavenLocal ()}}Copy the code

After assemble, execute the uploadArchives command:

./gradlew uploadArchives
Copy the code

2.3 Service Side

In the root gradle file of your project, configure the repository:

maven { url '.. /local_mavenrepo/'}Copy the code

Introduce dependencies in the corresponding module:

Implementation 'com. SDK. Aarpub: aar - test: 1.2.2'Copy the code

Third, problem summary

Aar file dependencies are not supported when building an aar…..

Reason: It is not allowed to rely directly on a local AAR when packaging an AAR. Solution: Make directly dependent local AArs dependent modules by placing dependent AArs in separate modules.

  1. Create a new folder, aar-lib
  2. Create a new liBS folderOaid_sdk_1. 0.30. The aarPut it in the LIBS directory

3. Create the build.gradle file and write the following content

Configurations. MaybeCreate (" default ") def publishArtifact = artifacts. The add (" default ", the file (' libs/oaid_sdk_1. 0.30. The aar))Copy the code
  1. Import this module in the project’s Settings file
include ':aar-lib'
Copy the code
  1. Delete the AAR file in the error module and replace the original dependency mode
// implementation Files ('libs/oaid_sdk_1.0.30.aar') old implementation Project (path:":aar-lib")Copy the code

3.2 Class reference failure caused by module’s dependence on AAR when packaging AAR

3.1 simply solves the problem of relying on local AArs during project packaging. When Module acts as an SDK and relies on AAR, an error will be reported when accessing the SDK, indicating that classes in aar cannot be referenced. Of course, we can directly introduce the AAR to the business test, but this increases the cost of access. Therefore, our solution works the same as 3.1, but uploads the AAR to a remote library for remote dependency.

For example, module A relies on OAID_SDK_1.0.30. aar, and as an SDK, module A is provided to the business side APP.

  1. Create an AAR-lib as 3.1, build.gradle with different contents:
Plugins {id 'maven-publish'} task androidJavadocs(type: Javadoc) { failOnError = false source = android.sourceSets.main.java.srcDirs ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar" classpath += files(ext.androidJar) } AndroidJavadocsJar (type: jar, dependsOn: AndroidJavadocs) {archiveClassifier. Set (' javadoc) from androidJavadocs. DestinationDir} / / packaged source code, this is very important for kotlin, Task androidSourcesJar(type: Jar) { archiveClassifier.set('sources') from android.sourceSets.main.java.srcDirs } configurations.maybeCreate("default") def publishArtifact = artifacts.add("default", File ('libs/oaid_sdk_1.0.30.aar') afterEvaluate{publishing {publications {myPublication(MavenPublication) {groupId 'com.sdk.aarpub' artifactId 'Aar-lib' version '1.0.0' // Your package version artifact(androidSourcesJar) Remove the artifact if you don't need it (androidJavadocsJar)// Pack annotations into the AAR if you don't need them // Push the AAR to the remote repository artifact publishArtifact //Example: *./target/myJavaClasses.jar* } } // Repositories *to* which Gradle can publish artifacts repositories { maven { url uri('.. /local_maverepo') // credentials { // username "default" // password "default" // } } } } }Copy the code
  1. Execute issue command
./gradlew :aar-lib:publish

Copy the code
  1. Make the A module depend on the remote AAR library pushed in step 2
Implementation 'com. SDK. Aarpub: aar - lib: 1.0.0'Copy the code
  1. Repackage the A module, and when the APP depends on the A module, the AAR in the A module will be referenced

Of course, when the A module is released, remember to bring dependencies:

// With dependencies, Node.withxml {def dependenciesNode = asNode(). AppendNode ('dependencies') def dependency = [configurations.compile] if (configurations.hasProperty("api")) { scopes.add(configurations.api) } if (configurations.hasProperty("implementation"))  { scopes.add(configurations.implementation) } if (configurations.hasProperty("debugImplementation")) { scopes.add(configurations.debugImplementation) } if (configurations.hasProperty("releaseImplementation")) { scopes.add(configurations.releaseImplementation) } // if (project.ext.targetType ! = "jar") { // scopes.add(configurations.provided) // } scopes.each { scope -> scope.allDependencies.each { if (it instanceof ModuleDependency) { boolean isTransitive = ((ModuleDependency) it).transitive if (! isTransitive) { println "<<<< not transitive dependency: [${it.group}, ${it.name}, ${it.version}]" return } } if (it.group == "${project.rootProject.name}.libs" || it.version == 'unspecified') { return }  if (it.group && it.name && it.version) { def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', it.group) dependencyNode.appendNode('artifactId', it.name) dependencyNode.appendNode('version', it.version) dependencyNode.appendNode('scope', scope.name) } } } }Copy the code

Four, reference

Use the Maven Publish plugin

# Maven Publish Plugin

# Resolve an issue where modules containing third-party AArs cannot be packaged to reference third-party classes directly

Aar file dependencies are not supported when building an aar.