Android SDK 開發——發布使用踩坑之路


前言

在 Android 開發過程中,有些功能是通用的,或者是多個業務方都需要使用的。

為了統一功能邏輯及避免重復開發,因此將該功能開發成一個 SDK 是相當有必要的。

背景

剛好最近自己遇到了類似需求,在開發完 SDK 之后,集成到項目或者提供給別人的時候遇到了一些坑,這里分享一下,以避免其他需要開發 SDK 的開發者們重復踩坑。

文章要說明的內容如下:

  1. 集成方式對比
  2. AAR 集成方式的一些坑
  3. 使用 maven publish 和 maven 將 SDK 推送到 maven 倉庫的區別
  4. Tips
  5. 總結

集成方式對比

SDK 開發完成之后,需要提供一種集成方式讓其他人可以使用。
集成方式這邊認為大概有 3 種。

1. 提供 Module

這種集成方式把整個 SDK 的源碼都提供給其他人。

優點:沒有什么坑,只要自己測試沒問題,別人一般可以直接使用。

缺點:后續如果有更新,需要全量給別人進行替換。
         而且項目里面如果同時引用多個Module,項目結構會增加很多代碼文件。
         還有可能一不小心就更改了 SDK。
         因為源碼可以直接修改,沒有任何保護。

2. 提供 AAR 文件

這種集成方式是把 SDK 編譯之后提供 AAR 文件給其他人。

優點:只有一個文件,不需要給到具體源碼。

缺點:某種情況下有坑,下面會講到。另外更新 SDK 不方便,每次更新需要用戶進行 AAR 文件替換。

3. 推送到倉庫(這里以 MAVEN 倉庫為例)(推薦)

這種集成方式是把 SDK 編譯之后的 AAR 文件推送到倉庫,后續可以通過 implementation 或者 api(舊版本 Gradle 為 compile)引用。

優點:集成方便,跟第三方庫集成類似,方便開發者。而且有版本管理。

缺點:maven publish 有個坑。見下文分析。

表格對比如下:

集成方式 優點 缺點
提供 Module 沒有坑 維護麻煩,沒有代碼保護
提供 AAR 文件 只有一個文件 有坑,更新麻煩
推送到倉庫 集成方便,版本管理 maven publish有個坑

AAR 集成方式的一些坑

一般 SDK 開發是封裝一些功能方便調用,因此比較少在 Module 里面引入第三方庫。這種情況下使用 AAR 集成是沒有太大問題的。

然而,當你的 SDK 中引入第三方庫,比如 Retorfit 之類的庫時(不是直接引入 jar 包或者 aar 包),這個時候你使用 AAR 集成,運行到對應代碼時會提示 java.lang.NoClassDefFoundError 錯誤。這個時候你

明明 Module 運行沒問題,怎么 AAR 就報錯了。

如果你嘗試在項目里面將 SDK 用到的第三方庫再引入一遍,就會發現程序沒報錯了。

因此我們可以得出結論:

AAR 不能傳遞第三方依賴

別慌,方法總比問題多。

我們可以通過將 SDK 推送到倉庫的方式來解決這個問題。

推送倉庫有很多,比如開源的 jcenter 之類的。

這邊考慮有些 SDK 是給公司內部使用的,因此以 maven 為例進行講解。

使用 maven publish 和 maven 將 SDK 推送到 maven 倉庫的區別

maven publish 其實是 maven 的一個升級。

所以一般優先采用 maven publish。

這邊項目已經使用了 maven publish 了,所以這邊一開始也是使用 maven publish。

結果坑來了。

發現出現和 AAR 一樣的錯誤,依賴不能傳遞。

這,趕緊看一眼 pom 文件(跟 AAR 同級目錄),發現真的沒有依賴。
查了一下網上資料。發現
https://discuss.gradle.org/t/using-the-maven-publish-plugin-no-dependencies-in-pom-xml/7599
有一個提問

當然應該有對應的處理方式,但是由於項目時間需求比較緊,不想花太多時間,因此暫時沒有查找解決方式。

如果有朋友知道,可以留言,后續有空研究,有解決方法也會更新。

因此這里不展開討論 maven publish 的集成方式。

最后查閱資料使用了 maven 的推送方式。

那么如何使用呢?
1.先使用本地倉庫,確保沒問題之后再使用遠程的
在 Module 的 build.gradle 文件中添加如下代碼:

apply plugin: 'maven' //指定使用 maven
uploadArchives {
    repositories {
        mavenDeployer {
            pom.groupId = "com.maven.demo" //包名
            pom.artifactId = "login"      //SDK 功能,自定義一個即可
            pom.version = "0.0.1"         //版本號
            repository(url: "file://localhost/Users/用戶名/Library/Android/sdk/extras/android/m2repository/") //用戶名替換為自己的機器名,本地地址
        }
    }
}

執行 uploadArchives 任務就可以上報了。

然后到上面 url 指定的目錄或者通過瀏覽器打開可以看到上傳的相關文件。

查看 pom 文件可以看到依賴都在上面。
2.使用遠程倉庫,對上面略做修改。

apply plugin: 'maven' //指定使用 maven
uploadArchives {
    repositories {
        mavenDeployer {
            pom.groupId = "com.maven.demo" //包名
            pom.artifactId = "login"      //SDK 功能,自定義一個即可
            pom.version = "0.0.1"         //版本號
            repository(url: "網址") {
                authentication(userName: "用戶名", password: "密碼")
            }
        }
    }
}

其中網址、用戶名和密碼記得分別替換。

別人需要使用時只需要在 Module 添加如下:

implementation 'com.maven.demo.login.0.01' 

所以倉庫的組成就是pom.groupId+pom.artifactId+pom.version

Tips:

1.SDK 開發可能遇到同一個版本比如 0.0.1 在發布之前經常需要修改的情況。

這個時候如果你把修改后的 SDK 推送到遠程,可能本地項目用的還是舊的內容。

這種時候有兩個處理方式。

第一個,更新版本號,修改依賴新版本。

第二個,執行下面命令,強制從遠程拉取,不使用緩存。

./gradlew build --refresh-dependencies

2.使用遠程倉庫時,一般用戶名和密碼都不會直接推送到代碼倉庫,可能會放到構建機。

這個時候需要使用類似於 local.properties 的外部文件來存放。

這個時候有個坑需要提醒一下,就是在 local.properties 定義比如 maven_user_name=username,千萬記得不要加雙引號,否則會出現認證失敗,出現下面提示:

Received status code 401 from server: Unauthorized

3.使用 maven 的形式如何指定是 debug 還是 release?

通過在 android 塊里面添加

android {
    defaultPublishConfig "release"
}

可以指定。

通過查看 Module 的 build/outputs/aar 可以看到 aar 包。

通過查看 Module 的 build/poms/pom-default.xml 可以看到本地 pom 文件。
4.有些開發者如果按照上面操作之后還是出現 java.lang.NoClassDefFoundError 錯誤,可以嘗試下面操作:

修改

implementation 'com.maven.demo.login.0.01' 

implementation 'com.maven.demo.login.0.01' {
        transitive = true
}

總結

  1. SDK 開發完成之后發布給其他人使用最好放到遠程倉庫(比如 maven)
  2. 如果出現 SDK 引入的第三方庫沒有找到的錯誤,記得到倉庫看下 pom 文件是否有對應依賴

關注公眾號一起交流:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM