日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Gradle实战:发布aar包到maven仓库

發(fā)布時(shí)間:2023/12/9 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Gradle实战:发布aar包到maven仓库 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

查看原文:http://blog.csdn.net/u0108184...

Gradle實(shí)戰(zhàn)系列文章:

《Gradle基本知識(shí)點(diǎn)與常用配置》
《Gradle實(shí)戰(zhàn):Android多渠道打包方案匯總》
《Gradle實(shí)戰(zhàn):不同編譯類型的包同設(shè)備共存》
《Gradle實(shí)戰(zhàn):執(zhí)行sql操作hive數(shù)據(jù)庫(kù)》


aar簡(jiǎn)介

aar文件是Google為Android開發(fā)所設(shè)計(jì)的一種library格式,全名為Android Archive Library,與Java Jar Library不同的是,aar除了java code之外還包含資源文件,即xml文件、圖片、文字等。
本文著重介紹發(fā)布過(guò)程和遇到的一些坑及其解決方案,文中的maven倉(cāng)庫(kù)是指公司搭建的maven倉(cāng)庫(kù),如果要發(fā)布到j(luò)Center或maven central,可以參考文章最后的“深入學(xué)習(xí)“。

1. 準(zhǔn)備工作

  • 開發(fā)工具:Android Studio;

  • 復(fù)習(xí)《Gradle基本知識(shí)點(diǎn)與常用配置》,本文會(huì)用到gradle中全局屬性設(shè)置、文件讀取、shell指令執(zhí)行等相關(guān)知識(shí)點(diǎn);

  • 工程必須是lib工程,即該工程對(duì)應(yīng)的build.gradle文件中要引用:

    apply plugin: 'com.android.library'

  • 在根目錄的build.gradle文件中添加

    allprojects {

    apply plugin: 'idea' apply plugin: 'maven'configurations {deployerJars }

    }

    configurations.all {

    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'//不使用緩存,使用倉(cāng)庫(kù)中最新的包

    }

    subprojects { //表示除主工程外所有子模塊

    dependencies {deployerJars "org.apache.maven.wagon:wagon-http:2.2" }

    }

    ext { //倉(cāng)庫(kù)選擇標(biāo)記

    repoType = "remote" //發(fā)布到遠(yuǎn)程倉(cāng)庫(kù)(下文中會(huì)用到)

    // repoType = "local" //發(fā)布到本地倉(cāng)庫(kù),方便調(diào)試,避免調(diào)試期間頻繁上傳到maven倉(cāng)庫(kù)(下文中會(huì)用到)
    }

  • 在gradle.properties文件中添加:

    releaseRepositoryUrl=xxx //正式包倉(cāng)庫(kù)地址(下文中會(huì)用到)
    snapshotRepositoryUrl=xxx //測(cè)試包倉(cāng)庫(kù)地址(下文中會(huì)用到)
    repositoryGroup=com.company.appname // 定義要上傳的aar所在倉(cāng)庫(kù)的Group,可自定義,但后續(xù)引用處要與此一致

  • 在工程根目錄下新建一個(gè)名為“mavenAccount.properties”文件,并將該文件加入到ignore 中,該文件用于存放訪問maven倉(cāng)庫(kù)的賬戶和密碼以及本地倉(cāng)庫(kù)地址,只有該模塊的開發(fā)者才有權(quán)發(fā)布該aar包。

    repositoryUserName=xxx
    repositoryPassword=xxx
    localRepositoryUrl=file:///Users/admin/Documents/Android/repo/

2. 編寫上傳腳本

  • 生成aar包

    > 在工程根目錄下新建一個(gè)名為“release-as-aar.gradle”的文件,其中腳本如下:

    uploadArchives() {

    repositories {mavenDeployer {configuration = configurations.deployerJarsprintln 'repoType : ' + rootProject.ext.repoTypeif ((rootProject.ext.repoType).equals("remote")) { //發(fā)布到遠(yuǎn)程倉(cāng)庫(kù)snapshotRepository(url: snapshotRepositoryUrl) { // 測(cè)試包//從本地文件讀取倉(cāng)庫(kù)賬號(hào)和密碼def File propFile = new File('../mavenAccount.properties')if (propFile.canRead()) {def Properties props = new Properties()props.load(new FileInputStream(propFile))if (props != null && props.containsKey('repositoryUserName') && props.containsKey('repositoryPassword')) {def repositoryUserName = props['repositoryUserName']def repositoryPassword = props['repositoryPassword']authentication(userName: repositoryUserName, password: repositoryPassword)println '上傳到遠(yuǎn)程倉(cāng)庫(kù)'} else {println '沒有發(fā)布權(quán)限'}} else {println '沒有發(fā)布權(quán)限'}}repository(url: releaseRepositoryUrl) { // 正式包def File propFile = new File('../mavenAccount.properties')if (propFile.canRead()) {def Properties props = new Properties()props.load(new FileInputStream(propFile))if (props != null && props.containsKey('repositoryUserName') && props.containsKey('repositoryPassword')) {def repositoryUserName = props['repositoryUserName']def repositoryPassword = props['repositoryPassword']authentication(userName: repositoryUserName, password: repositoryPassword)println '上傳到遠(yuǎn)程倉(cāng)庫(kù)'} else {println '沒有發(fā)布權(quán)限'}} else {println '沒有發(fā)布權(quán)限'}}} else { // 發(fā)布到本地倉(cāng)庫(kù)def localRepositoryUrldef File propFile = new File('../mavenAccount.properties')if (propFile.canRead()) {def Properties props = new Properties()props.load(new FileInputStream(propFile))if (props != null && props.containsKey('localRepositoryUrl')) {localRepositoryUrl = props['localRepositoryUrl']snapshotRepository(url: localRepositoryUrl)repository(url: localRepositoryUrl)println '上傳到本地倉(cāng)庫(kù)'} else {println '沒有發(fā)布權(quán)限'}} else {println '沒有發(fā)布權(quán)限'}}} }

    }

  • 生成jar包

    > 在工程根目錄下新建一個(gè)名為“release-as-jar.gradle”的文件,其中腳本如下:

    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)

    }

    task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {

    classifier = 'javadoc' from androidJavadocs.destinationDir

    }

    task androidSourcesJar(type: Jar) {

    classifier = 'sources' from android.sourceSets.main.java.srcDirs

    }

    uploadArchives {

    repositories {mavenDeployer {configuration = configurations.deployerJarsprintln 'repoType : ' + rootProject.ext.repoTypeif ((rootProject.ext.repoType).equals("remote")) { //發(fā)布到遠(yuǎn)程倉(cāng)庫(kù)snapshotRepository(url: snapshotRepositoryUrl) {def File propFile = new File('../mavenAccount.properties')if (propFile.canRead()) {def Properties props = new Properties()props.load(new FileInputStream(propFile))if (props != null && props.containsKey('repositoryUserName') && props.containsKey('repositoryPassword')) {def repositoryUserName = props['repositoryUserName']def repositoryPassword = props['repositoryPassword']authentication(userName: repositoryUserName, password: repositoryPassword)println '上傳到遠(yuǎn)程倉(cāng)庫(kù)'} else {println 'sorry,你沒有上傳aar包的權(quán)限'}} else {println 'sorry,你沒有上傳aar包的權(quán)限'}}repository(url: releaseRepositoryUrl) {def File propFile = new File('../mavenAccount.properties')if (propFile.canRead()) {def Properties props = new Properties()props.load(new FileInputStream(propFile))if (props != null && props.containsKey('repositoryUserName') && props.containsKey('repositoryPassword')) {def repositoryUserName = props['repositoryUserName']def repositoryPassword = props['repositoryPassword']authentication(userName: repositoryUserName, password: repositoryPassword)println '上傳到遠(yuǎn)程倉(cāng)庫(kù)'} else {println 'sorry,你沒有上傳aar包的權(quán)限'}} else {println 'sorry,你沒有上傳aar包的權(quán)限'}}} else {//發(fā)布到本地倉(cāng)庫(kù)def localRepositoryUrldef File propFile = new File('../mavenAccount.properties')if (propFile.canRead()) {def Properties props = new Properties()props.load(new FileInputStream(propFile))if (props != null && props.containsKey('localRepositoryUrl')) {localRepositoryUrl = props['localRepositoryUrl']snapshotRepository(url: localRepositoryUrl)repository(url: localRepositoryUrl)println '上傳到本地倉(cāng)庫(kù)'} else {println 'sorry,本地倉(cāng)庫(kù)路徑不存在'}} else {println 'sorry,本地倉(cāng)庫(kù)路徑不存在'}}} }

    }

    artifacts {

    archives androidSourcesJar archives androidJavadocsJar

    }

3. 子模塊中相關(guān)配置

  • 在子模塊的build.gradle文件中添加:

    group repositoryGroup
    //version '0.0.1'
    version '0.0.1-SNAPSHOT' //表示測(cè)試版,正式發(fā)版時(shí)去掉“-SNAPSHOT”

    //打成aar格式
    apply from: '../release-as-aar.gradle' //引用上傳插件

    //打成jar格式
    //apply from: '../release-as-jar.gradle'

4. 打包上傳

  • 編譯通過(guò)后,打開android studio自帶的終端,進(jìn)入相應(yīng)的module目錄下,輸入:gradle uploadArchives

5. 使用aar

  • 在需要引用aar包的工程中,根目錄的build.gradle文件中進(jìn)行如下配置:

    allprojects {

    repositories {

    // jcenter(); //注釋jcenter,表示不直接從jcenter倉(cāng)庫(kù)獲取,而是通過(guò)公司私服倉(cāng)庫(kù)去獲取

    maven {name 'xxx' //key與value之間有空格url 'xxx' //key與value之間有空格}mavenLocal(); }

    }

  • 在子模塊的build.gradle文件中進(jìn)行如下引用:

    dependencies {

    compile group: repositoryGroup, name: 'xxx', version: '0.0.1', ext: 'aar', changing: true

    }

6. 踩到的坑

  • 問題一:上傳時(shí)找不到服務(wù)器

上傳時(shí)需關(guān)閉android studio的翻墻代理設(shè)置,且注釋settings.gradle中自動(dòng)生成的代理服務(wù)器相關(guān)配置,否則上傳時(shí)會(huì)報(bào)找不到倉(cāng)庫(kù)服務(wù)器的錯(cuò)誤。

  • 問題二:aar包無(wú)法更新

有時(shí)上傳了最新的snapshot包,引用的地方也sync、clean了,但引用的還是舊的包,此時(shí)需要?jiǎng)h除“~/.gradle”中的相關(guān)記錄。為方便執(zhí)行,我們可以在應(yīng)用工程根目錄的build.gradle文件中,采用shell命令刪除,該命令會(huì)在你執(zhí)行clean操作時(shí)先執(zhí)行:

task deleteDescriptors(type: Exec) { //執(zhí)行shell命令executable "sh"args "-c", "rm -rf ~/.gradle/caches/modules-2/metadata-2.16/descriptors/com.company.appname" //此處的“com.company.appname“就是之前定義的“repositoryGroup“。}task clean(type: Delete, dependsOn: deleteDescriptors) { //clean工程時(shí)順帶執(zhí)行上述任務(wù)delete rootProject.buildDir}

此時(shí),再clean一下,引用的就是最新的aar包了。

  • 問題三:無(wú)法設(shè)置debug編譯類型

在lib工程中無(wú)論怎么設(shè)置編譯類型,最后生成的aar包中始終都是release版本,該問題見google反饋。既然不可設(shè)置編譯類型,我們可以在aar包代碼中通過(guò)反射來(lái)獲取應(yīng)用的編譯類型:

private Object getBuildConfigValue(Context context, String fieldName) {try {Class<?> clazz = Class.forName(context.getPackageName() + ".BuildConfig");Field field = clazz.getField(fieldName);return field.get(null);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return null;}//使用String buildType = getBuildConfigValue(ctx,"BUILD_TYPE").toString();if (!TextUtils.isEmpty(buildType) && buildType.equals("debug")) { // debug...} else { // release...}

但是,這里面還有一個(gè)坑,系統(tǒng)版本在4.4以下的設(shè)備中,該方法無(wú)法獲得包名,會(huì)拋空指針錯(cuò)誤。以下我們給出完整的解決方案:

public class BuildConfigProvider {private static Context sContext;private static String packageName;public static String getBuildType() {String buildType = (String) getBuildConfigValue("BUILD_TYPE");if ("debug".equals(buildType)) {buildType = "debug";}if ("release".equals(buildType)) {buildType = "release";}return buildType;}public static final boolean isDebug() {return BuildConfig.DEBUG;}/*** 通過(guò)反射獲取ApplicationContext** @return*/private static Context getContext() {if (sContext == null) {try {final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");final Method currentActivityThread = activityThreadClass.getDeclaredMethod("currentActivityThread");final Object activityThread = currentActivityThread.invoke(null);final Method getApplication = activityThreadClass.getDeclaredMethod("getApplication");final Application application = (Application) getApplication.invoke(activityThread);sContext = application.getApplicationContext();} catch (Exception e) {e.printStackTrace();}}return sContext;}/*** 通過(guò)反射獲取包名** @return*/private static String getPackageName() {if (packageName == null) {try {final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");final Method currentPackageName = activityThreadClass.getDeclaredMethod("currentPackageName");packageName = (String) currentPackageName.invoke(null);} catch (Exception e) {packageName = getContext().getPackageName();}}return packageName;}public static Object getBuildConfigValue(String fieldName) {try {Class<?> clazz = Class.forName(packageName + ".BuildConfig");Field field = clazz.getField(fieldName);return field.get(null);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IndexOutOfBoundsException e) {e.printStackTrace();}return "";}}

當(dāng)然,有人可能會(huì)說(shuō),既然可以通過(guò)反射得到ApplicationContext,就沒必要再去反射獲得包名了,這里只是提供不同的解決方案以作參考。

  • 問題四:多包共存模式下獲得編譯類型為空

在上一篇博客《 Gradle實(shí)際應(yīng)用(二):同名包共存》中,我們可以在一個(gè)設(shè)備中安裝同一個(gè)應(yīng)用不同編譯類型的包。但是,非release包中我們獲得的包名是帶有編譯類型后綴的(如“com.company.appname.debug“),而編譯類型我們是通過(guò)反射獲取,“BuildConfig“所在的包名還是原始的、不加后綴的包名(如“com.company.appname“),此時(shí)我們拿到的編譯類型為空,那么我們可以在獲取包名后做一個(gè)檢查:

private static String checkPackageName(String packageName) {String[] temp = packageName.split("\\.");String sub = temp[temp.length - 1];//如果多包共存模式,剔除包名中的后綴if (sub.equals("debug")) {StringBuilder sb = new StringBuilder();for (int i = 0; i < temp.length - 1; i++) {sb.append(temp[i]);if (i != temp.length - 2) {sb.append(".");}}packageName = sb.toString();}return packageName;}

深入學(xué)習(xí)

  • 同步aar到j(luò)Center與maven central

  • Android Studio使用Gradle上傳AAR至Maven

  • aar無(wú)法設(shè)置debug問題解決參考

查看原文:http://blog.csdn.net/u0108184...

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的Gradle实战:发布aar包到maven仓库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。