網站首頁 編程語言 正文
背景
平時開發中會把一些獨立的功能模塊抽取出來作為sdk,既方便業務接入,又能讓其他業務線快速復用。那么我們就需要將sdk打包上傳到maven倉庫,讓業務側依賴即可。
一、編譯后的產物
在上傳產物到maven倉庫之前,我們的知道產物到底是什么。
Android Gradle插件根據項目gradle中應用不同的插件類型在編譯組裝后會生成不同的產物:
1.1 APK 構件
Android項目的主工程app的gradle配置文件依賴:
apply plugin: 'com.android.application'
因此,在通過編譯命令./gradlew assembleDebug
?或./gradlew assembleRelease
后,就會在build/outputs/apk文件下生成產物:
如圖,apk就是產物(構件)。
1.2 AAB(Android app bundle)構件
如果是海外市場,在Google Play上架的應用必須要打aab包,而不是之前的apk格式。具體區別就暫不討論了~ 編譯命令為:./gradlew bundleDebug
?或./gradlew bundleRelease
。產物為:
1.3 AAR 構件
一般的module在編譯打包后,會生成aar:
二、publish插件
有了產物,我們就需要把產物上傳到maven倉庫(一般是私有倉庫),方便公司項目直接依賴。而上傳就要用到publish插件。APG 3.6.0之前用的maven
插件,之后都用maven-publish
插件。
2.1 maven-publish插件使用
我們可以新建一個gradle文件,如:maven_publish.gradle。專門用來上傳aar。配置如下:
//maven-publish 新方式 plugins { //todo 1 上傳插件 id 'maven-publish' } afterEvaluate{ publishing { publications { // Creates a 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* artifact "build/outputs/aar/aar-test-release.aar"http://aar包的目錄 //帶上依賴 ,否則會報錯 pom.withXml { def dependenciesNode = asNode().appendNode('dependencies') def scopes = [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 { //上傳到項目本地倉庫 url uri('../local_mavenrepo') // credentials { // username "default" // password "default" // } } } } }
在assemble命令后,執行publish命令:
./gradlew publish
2.2 maven插件使用
舊方式:
plugins { //todo 1 上傳插件 id 'maven' } uploadArchives{ // 方式一 repositories { mavenDeployer{ repository(url: uri('../local_mavenrepo')) //todo 2 配置版本信息 方式二 pom.groupId = 'com.sdk.aarpub' pom.artifactId = 'aar-test' pom.version = '1.1.0' } //mavenLocal 這個是本機上的maven本地緩存倉庫 // mavenLocal() } }
在assemble命令后,執行uploadArchives命令:
./gradlew uploadArchives
2.3 業務側使用
在項目的根gradle文件中,配置倉庫:
maven { url '../local_mavenrepo/'}
在對應的模塊中引入依賴:
implementation 'com.sdk.aarpub:aar-test:1.2.2'
三、問題總結
3.1 報錯
項目中依賴本地aar的時候打包報錯Direct local .aar file dependencies are not supported when building an AAR.....
原因:當打包aar時候直接依賴本地的aar是不被允許的。 解決方案:通過把依賴的aar放到單獨的模塊中,讓直接依賴本地aar變成依賴模塊。
- 新建一個文件夾aar-lib
- 新建一個libs文件夾,把
oaid_sdk_1.0.30.aar
放入到libs目錄中?
新建build.gradle文件,寫入如下內容:
configurations.maybeCreate("default") def publishArtifact = artifacts.add("default", file('libs/oaid_sdk_1.0.30.aar'))
在項目的settings文件中引入該模塊:
include ':aar-lib'
刪除報錯模塊中的aar文件,替換原來依賴方式:
// implementation files('libs/oaid_sdk_1.0.30.aar') 舊的方式 implementation project(path:":aar-lib")
3.2 module打包aar時依賴aar導致的類引用不到的問題
3.1 只是解決了在項目打包過程中依賴本地aar的問題。 當module作為sdk同時又依賴aar時,此時接入sdk會報錯,提示引用不到aar中的類。當然我們可以直接把aar給到業務測,直接引入即可,但這樣增加了接入成本。因此,我們的解決方案跟原理跟3.1一樣,但是會把aar上傳到遠程庫,作為遠程來依賴。
比如 A模塊依賴了oaid_sdk_1.0.30.aar,同時A模塊作為sdk是要提供給業務側app使用的。
按照3.1的方式創建一個aar-lib,build.gradle內容有所不同:
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) } //將文檔打包成jar task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { archiveClassifier.set('javadoc') from androidJavadocs.destinationDir } //將源碼打包,這一點對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)//將源碼打包進aar,如果不需要可以去掉 artifact(androidJavadocsJar)//將注釋打包進aar,如果不需要可以去掉 // 將aar推送到遠程倉庫 artifact publishArtifact //Example: *./target/myJavaClasses.jar* } } // Repositories *to* which Gradle can publish artifacts repositories { maven { url uri('../local_maverepo') // credentials { // username "default" // password "default" // } } } } }
執行發布命令:
./gradlew :aar-lib:publish
讓A模塊依賴第二步中推送到遠程的aar庫:
implementation 'com.sdk.aarpub:aar-lib:1.0.0'
- 重新打包A模塊,當app依賴A模塊時候,A模塊中的aar就會被引用到了 當然在A模塊發布的時候記得要帶上依賴:
//帶上依賴 ,否則會報錯 pom.withXml { def dependenciesNode = asNode().appendNode('dependencies') def scopes = [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) } } } }
原文鏈接:https://juejin.cn/post/7064160157604773925
相關推薦
- 2022-02-27 報錯:Unable to find main class
- 2022-06-13 golang下grpc框架的使用編寫示例_Golang
- 2022-08-11 C++超詳細講解強制類型轉換的用法_C 語言
- 2022-12-23 Python異常信息的不同展現方法總結_python
- 2023-01-13 Android?Parcleable接口的調用源碼層分析_Android
- 2022-11-05 一篇文章說清楚?go?get?使用私有庫的方法_Golang
- 2023-09-12 git 忽略掉不需要的文件
- 2022-12-14 Rocksdb?Memtable數據結構源碼解析_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支