Android SDK 開發紀要

一、前言

筆者在做Android SDK開發的過程中,也算從0到1,遇坑填坑了,今天分享的是在封裝aar時遇到的那些坑,以及對SDK設計的改進等等。

二、配置清單

1、AndroidManifest,若SDK在配置清單中申請許可權,編譯時就會報合併重複錯誤,只能去除主項目中原有的聲明。因此,不建議在SDK內部聲明,應改為在接入文檔中說明,由主項目配置。

2、<application/> 標籤,常見默認屬性如:android:nameandroid:themeandroid:lable... 如無切實必要,請去除這些屬性,避免打包時與主項目衝突。

三、Gradle文件

打包編譯重命名,抽取aar+版本號自動重命名並複製到指定目錄下

apply plugin: com.android.librarystatic def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))}android { compileSdkVersion 25 buildToolsVersion 26.0.2 defaultConfig { minSdkVersion 19 targetSdkVersion 25 versionCode 6 versionName "5.1.0" } ... repositories { flatDir { dirs libs } } libraryVariants.all { variant -> if (variant.buildType.name == release) { variant.assemble.doLast { variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith(release.aar)) { def fileName = "${project.name}-release-${android.defaultConfig.versionName}-${releaseTime()}" def outputPath = "/build/aar" copy { from outputFile into outputPath } copy { from outputFile into outputPath rename { fileName + ".aar" } } } } } } }}dependencies { implementation fileTree(include: [*.jar], dir: libs) androidTestImplementation(com.android.support.test.espresso:espresso-core:2.2.2, { exclude group: com.android.support, module: support-annotations }) testImplementation junit:junit:4.12 implementation com.android.support:appcompat-v7:25.4.0}

四、資源id命名規範

Values中的colors、strings、styles中的id命名應當注意保持一定的唯一性(如:命名統一加項目前綴),避免與主項目中的資源id衝突,造成SDK中的資源被覆蓋,如theme、string等等。

當然,從另一個角度來看,這個特性也可以作為定製UI的一個思路,用主項目中定義的相同資源覆蓋掉SDK中的資源屬性,從而實現靈活改變SDK的樣式。

五、避免創建Application對象

若SDK中定義了Application對象,而主項目也定義了Application或者應用了第三方Application,則需將android:name屬性替換掉,才能正常編譯,因為一個App只能指定一個Application,若直接替換,則會造成SDK中的Application無法初始化,引起一大波問題。

解決方案有二:

1、避免在SDK中創建Application對象,暴露出一個初始化方法,在主項目的Application相關方法如onCreate()中注入相關參數執行;

2、若無法避免,則可指定主項目的Application繼承自SDK中的內置Application,問題可以解決。

/** * <pre> * author : fdm * time : 2018/03/09 * desc : SDK初始化 * version: 1.0 * </pre> */public class MySDK { private static Context sContext; public MySDK() { } //提供給第三方調用,進行初始化 public static void initSDK(Context context) { sContext = context; initLog(context); } private static void initLog(Context context) { new LogUtil.Builder(context) .setLogSwitch(true) .setGlobalTag("fdm") .setLogHeadSwitch(true) .setLogFilter(LogUtil.D); } public static Context getContext() { return sContext; }}

六、無法將第三方庫打包進aar的問題

library打包出來的 AAR ,不會將依賴的第三方庫打包進去。這個問題也是由來已久,詳情可見: Android Studio how to package single AAR from multiple library projects?

解決方案有兩個:

1、將AAR發布到遠程倉庫,這樣gradle依賴下來的時候就會自動依賴第三方庫了。

2、在主項目中顯式指定SDK中的第三方依賴包,如常見的gson、okhttp等等...

七、混淆問題

在Android開發中,我們一般都會對代碼進行混淆後發布,所以在測試SDK時必須考慮到這個情況。

默認情況下,proguard-rules.pro中的混淆配置是不會被打包進aar中的,所以一般需要在主項目中手動指定混淆規則。

但是,為了提高接入體驗,能否將SDK中的混淆配置也打包進aar中,讓項目自動配置SDK的混淆文件呢?答案是肯定的,我們可以指定consumerProguardFiles屬性,自定義引入的混淆規則,即可將*.pro文件打包進入aar中,項目打包時就會自動合併該配置文件。 值得一提的是該屬性只鎮對library有效,對app無效。

consumerProguardFiles配置如下:

defaultConfig { minSdkVersion 17 targetSdkVersion 26 versionCode 1 versionName "1.0" consumerProguardFiles proguard-rules.pro//一行代碼解決SDK內部混淆問題 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"}

八、結語

今天的分享就到這裡了,由於本人水平所限,內容難免錯漏,歡迎批評指正!

系列文章:

Android SDK開發與使用的那些事兒

二次打包(封裝)AAR實用指南


推薦閱讀:

矽谷和國內的 iOS 開發到底有何不同?
廣告sdk竊取用戶隱私:你家的App被下架了嗎?
聽阿里雲工程師談談如何開發一個優秀的SDK
手游第三方服務商興衰史:建立核心競爭壁壘方能始終

TAG:Android開發 | Android | SDK |