一.環(huán)境準(zhǔn)備
首先需要特定版本的AndroidStudio爱沟,由于AndroidStudio與gradle版本相關(guān)聯(lián),所以也需要注意gradle版本匆背,如下是我的AndroidStudio與gradle版本
在gradle-wrapper.properties中配置gradle版本如下:
#Sun Aug?2214:48:51CST?2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
在Settings中的build.gradle中g(shù)radle配置如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
????ext.kotlin_version =?'1.8.10'
????repositories {
????????google()
????????jcenter()
????????mavenCentral()
????}
????dependencies {
????????classpath?"com.android.tools.build:gradle:4.1.3"
????????classpath?"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
????????classpath?'com.google.protobuf:protobuf-gradle-plugin:0.8.17'
????????// NOTE: Do not place your application dependencies here; they belong
????????// in the individual module build.gradle files
????}
}
allprojects {
????repositories {
????????google()
????????jcenter()
????}
????gradle.projectsEvaluated {
????????tasks.withType(JavaCompile) {
????????????options.compilerArgs.add("-Xbootclasspath/p:${project.rootDir}/libs/framework.jar")
????????}
????}
}
task clean(type: Delete) {
????delete rootProject.buildDir
}
如果沒有上面AndroidStudio版本可以進(jìn)行下載呼伸,不用卸載原先的AndroidStudio,是可以運行多個不同版本的AndroidStudio的钝尸,AndroidStudio下載地址:Android Studio 下載文件歸檔 ?|? Android 開發(fā)者 ?|? Android Developers
Java版本如下:
二.理解Settings Android.bp文件里面的依賴關(guān)系
首先我們找到Settings項目位置:QCM6125_Android13.0_R04_r020\QSSI.13\packages\apps\Settings
然后分析Settings里面的Android.bp文件
package{
????default_applicable_licenses: ["packages_apps_Settings_license"],
}
// Added automatically by a large-scale-change
// See:http://go/android-license-faq
license {
????name:?"packages_apps_Settings_license",
????visibility: [":__subpackages__"],
????license_kinds: [
????????"SPDX-license-identifier-Apache-2.0",
????],
????license_text: [
????????"NOTICE",
????],
}
java_library {
????name:?"settings-logtags",
????srcs: ["src/**/*.logtags"],
}
genrule {
????name:?"statslog-settings-java-gen",?????????????????//此模塊是調(diào)用命令括享,生成auto generating code
????tools: ["stats-log-api-gen"],
????cmd:?"$(location stats-log-api-gen) --java $(out) --module settings"
????????+?" --javaPackage com.android.settings.core.instrumentation --javaClass SettingsStatsLog",
????out: ["com/android/settings/core/instrumentation/SettingsStatsLog.java"],
}
java_library {
????name:?"statslog-settings",??????????//此模塊使用自動生成的代碼搂根,生成statslog-settings.jar包
????srcs: [
????????":statslog-settings-java-gen",
????],
}
soong_config_module_type_import {
????from:?"device/qcom/qssi/Android.bp",
????module_types: [
?????????"bredr_vs_btadva_java_defaults",
????],
}
bredr_vs_btadva_java_defaults {
????name:?"btadva_settings_java_defaults",
????soong_config_variables: {
????????bredr_or_btadva: {
???????????btadva: {
??????????????srcs: [
?????????????????":settings-bluetooth-adva-srcs",
??????????????],
???????????}
???????}
???}
}
// Build the Settings APK?????? //生成APK相關(guān)內(nèi)容
android_library {???????????????//此模塊是生成一個JAR LIBRARY
????name:?"Settings-core",??????//生成的模塊名稱為:Settings-core
????platform_apis:?true,????????//獲取訪問@hide API的權(quán)限,谷歌發(fā)布的SDK是不包含隱藏API的
????defaults: [
????????"SettingsLibDefaults",??????//使用名為SettingsLibDefaults的模塊defaults配置铃辖,從名字得知還需要引入SettingsLib相關(guān)模塊
????????"SettingsLib-search-defaults",??????//使用名為SettingsLib-search-defaults的模塊defaults配置
????????"framework-wifi-vendor-hide-access-defaults",????//使用名為framework-wifi-vendor-hide-access的模塊defaults配置
????????"btadva_settings_java_defaults",?????//使用名為btadva_settings_java的模塊defaults配置
????],
????srcs: ["src/**/*.java",?"src/**/*.kt"],
????static_libs: [
????????"androidx-constraintlayout_constraintlayout",
????????"androidx.slice_slice-builders",
????????"androidx.slice_slice-core",
????????"androidx.slice_slice-view",
????????"androidx.core_core",
????????"androidx.appcompat_appcompat",
????????"androidx.cardview_cardview",
????????"androidx.preference_preference",
????????"androidx.recyclerview_recyclerview",
????????"androidx.window_window",
????????"com.google.android.material_material",
????????"setupcompat",
????????"setupdesign",
????????"androidx.lifecycle_lifecycle-runtime",
????????"androidx.lifecycle_lifecycle-extensions",
????????"guava",
????????"jsr305",
????????"net-utils-framework-common",
????????"settings-contextual-card-protos-lite",
????????"settings-log-bridge-protos-lite",
????????"settings-telephony-protos-lite",
????????"contextualcards",
????????"settings-logtags",
????????"statslog-settings",
????????"zxing-core-1.7",
????????"android.hardware.dumpstate-V1.0-java",
????????"android.hardware.dumpstate-V1.1-java",
????????"lottie",
????????"WifiTrackerLib",
????????"SettingsLibActivityEmbedding",
????],
????libs: [?????//# Settings-core?? 模塊依賴的動態(tài)庫列表
????????"telephony-common",
????????"ims-common",
????????"app-compat-annotations",
????????"telephony-ext",
????????"extphonelib",
????],
}
platform_compat_config {
????name:?"settings-platform-compat-config",
????src:?":Settings-core",??????//依賴Settings-core模塊
????system_ext_specific:?true,??????//編譯生成的文件將存放到/system/system_ext/ 目錄
}
android_app {???????//生成APK的模塊
????name:?"Settings",???????//生成的APK名為:Settings.apk
????defaults: ["platform_app_defaults"],???
????platform_apis:?true, ?//授權(quán)使用@hide API
????certificate:?"platform", ?//采用系統(tǒng)簽名 ? ?
????system_ext_specific:?true,???????//結(jié)合privilege:true,編譯生成的文件剩愧,將存放到/system/system_ext/pri-app中
????privileged:?true,???????//是否存放在priv-app 目錄
????required: [
????????"privapp_whitelist_com.android.settings",
????????"settings-platform-compat-config",
????],
????static_libs: ["Settings-core"],?????????//靜態(tài)依賴于Settings-core 模塊
????uses_libs: ["org.apache.http.legacy"],
????resource_dirs: [],
????optimize: {
????????proguard_flags_files: ["proguard.flags"],
????},
????libs: [
????????"extphonelib"
????],
}
android_library_import {
????name:?"contextualcards",????????//名為contextualcards.aar模塊
????aars: ["libs/contextualcards.aar"],
}
filegroup {
????name:?"Settings_proguard_flags",
????srcs: ["proguard.flags"],
}
// The sources for Settings need to be exposed to SettingsGoogle, etc.
// so they can run the com.android.settingslib.search.IndexableProcessor
// over all the sources together.
filegroup {
????name:?"Settings_srcs",
????srcs: ["src/**/*.java"],
}
filegroup {
????name:?"Settings_manifest",
????srcs: ["AndroidManifest.xml"],
}
分析結(jié)果:
1.生成Settings.apk的android_app編譯配置,通過Settings-core間接依賴于srcs:["src/**/*java"]
所以未直接使用自己目錄下的源碼來生成
若依照此配置構(gòu)建AS工程娇斩,則工程中沒有Settings源碼仁卷,而是由各種庫組成
我們構(gòu)建AS工程,本身是為了調(diào)試Settings源碼犬第,所以jar就失去了構(gòu)建AS工程的意義
結(jié)論:我們構(gòu)建的Settings AS工程锦积,其Settings.app的build.gradle將直接依賴源碼,而不是Settings-core.jar
2.從Settings-core模塊的defaults應(yīng)用得知瓶殃,我們還需要依賴模塊:SettiingsLibDefaults和SettingsLib-search-defaults
從后續(xù)SettingsLib的依賴分析得知充包,Settings需要依賴于SettingsLib,所以我們還得繼續(xù)分析SettingsLib的Android.bp
3.以androidx開頭的遥椿,均為安卓的支持庫基矮,通過Maven遠(yuǎn)程倉庫獲取
三.理解SettingsLib中的Android.bp文件中依賴關(guān)系
上面說了Settings中需要依賴SettingsLib慨飘,首先我們找到SettingsLib的位置:\\10.66.100.21\disk1\project\QCM6125_Android13.0_R04_r020\QSSI.13\frameworks\base\packages\SettingsLib
然后分析里面的Android.bp文件
package{
????// See:http://go/android-license-faq
????// A large-scale-change added 'default_applicable_licenses' to import
????// all of the 'license_kinds' from "frameworks_base_license"
????// to get the below license kinds:
????//?? SPDX-license-identifier-Apache-2.0
????default_applicable_licenses: ["frameworks_base_license"],
}
soong_config_module_type_import {
????from:?"device/qcom/qssi/Android.bp",
????module_types: [
?????????"bredr_vs_btadva_java_defaults",
????],
}
bredr_vs_btadva_java_defaults {
????name:?"btadva_settings_lib_java_defaults",
????soong_config_variables: {
????????bredr_or_btadva: {
???????????btadva: {
??????????????srcs: [
?????????????????":framework-settingslib-adva-srcs",
??????????????],
???????????}
???????}
???}
}
android_library {
????name:?"SettingsLib",????????????//模塊名稱 SettingsLib.jar
????defaults: [
????????"framework-wifi-vendor-hide-access-defaults",???//引用名
????????"btadva_settings_lib_java_defaults",????????????//引用名
????],
????static_libs: [??//靜態(tài)依賴档玻,SettingsLib都需要依賴下面模塊
????????"androidx.annotation_annotation",
????????"androidx.legacy_legacy-support-v4",
????????"androidx.recyclerview_recyclerview",
????????"androidx.preference_preference",
????????"androidx.appcompat_appcompat",
????????"androidx.lifecycle_lifecycle-runtime",
????????"androidx.mediarouter_mediarouter-nodeps",
????????"com.google.android.material_material",
????????"iconloader",
????????"WifiTrackerLib",
????????"WifiTrackerLibRes",
????????"SettingsLibHelpUtils",
????????"SettingsLibRestrictedLockUtils",
????????"SettingsLibActionBarShadow",
????????"SettingsLibAppPreference",
????????"SettingsLibSearchWidget",
????????"SettingsLibSettingsSpinner",
????????"SettingsLibIllustrationPreference",
????????"SettingsLibLayoutPreference",
????????"SettingsLibMainSwitchPreference",
????????"SettingsLibActionButtonsPreference",
????????"SettingsLibEntityHeaderWidgets",
????????"SettingsLibBarChartPreference",
????????"SettingsLibProgressBar",
????????"SettingsLibAdaptiveIcon",
????????"SettingsLibRadioButtonPreference",
????????"SettingsLibSelectorWithWidgetPreference",
????????"SettingsLibDisplayDensityUtils",
????????"SettingsLibUtils",
????????"SettingsLibEmergencyNumber",
????????"SettingsLibTopIntroPreference",
????????"SettingsLibBannerMessagePreference",
????????"SettingsLibFooterPreference",
????????"SettingsLibUsageProgressBarPreference",
????????"SettingsLibCollapsingToolbarBaseActivity",
????????"SettingsLibTwoTargetPreference",
????????"SettingsLibSettingsTransition",
????????"SettingsLibButtonPreference",
????????"setupdesign",
????????"zxing-core-1.7",
????],
????// ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
????// LOCAL_SHARED_JAVA_LIBRARIES := androidx.lifecycle_lifecycle-common
????resource_dirs: ["res"],
????srcs: [
????????"src/**/*.java",
????????"src/**/*.kt",
????],
????min_sdk_version:?"29",
}
// NOTE: Keep this module in sync with ./common.mk
java_defaults {
????name:?"SettingsLibDefaults",????????//"Settings-core"模塊默認(rèn)引用的一組名為SettingsLibDefaults的配置
????static_libs: [
????????"androidx.annotation_annotation",
????????"androidx.lifecycle_lifecycle-common",
????????"androidx.legacy_legacy-support-v4",
????????"androidx.lifecycle_lifecycle-runtime",
????????"androidx.recyclerview_recyclerview",
????????"androidx.preference_preference",
????????"androidx.appcompat_appcompat",
????????"androidx.legacy_legacy-preference-v14",
????????"SettingsLib",??????//“Settings-core”通過"SettingsLibDefaults"間接引用了"SettingsLib"
????],
}
分析結(jié)果
1.因為"Settings-core"模塊默認(rèn)引用的一組名為"SettingsLibDefaults"的配置,所以我們需要先解決"SettingsLibDefaults"
2.通過對"SettingsLibDefaults"分析爵政,我們得知碴裙,需要引入"SettingsLib"的模塊钢悲,此模塊負(fù)責(zé)編譯srcs:["src//*.java","src//*.kt"]
3.“SettingsLib”依賴于WifiTrackerLib、WifiTrackerLibRes模塊
4.“SettingsLib”模塊還依賴于一連串的子模塊舔株,例如:"SettingsLibHelpUtils"..."SettingsLibButtonPreference"
5.“SettingsLib”模塊還依賴于一些其他模塊莺琳,"setupdesign"、"zxing-core-1.7"载慈、"iconloader"
6."SettingsLib"模塊依賴于一些Androidx為安卓支持庫惭等,可以直接通過maven倉獲取。
四.靜態(tài)庫與動態(tài)庫的依賴方式
1.靜態(tài)鏈接庫:static_libs
靜態(tài)庫特點:
每一個被static_libs命名的模塊办铡,他的數(shù)據(jù)都會被合并到目標(biāo)apk中
同時辞做,這些static_libs還將承擔(dān)編譯時被引用符號的解析工作
例如:
? ? static_libs: ["android.hardware.dumpstate-V1.1-java"],
轉(zhuǎn)換成build.gradle:
implementation files('../libs/android.hardware.dumpstate-V1.1-java.jar')
2.動態(tài)庫鏈接:shared_libs、libs
與靜態(tài)鏈接庫的區(qū)別寡具,動態(tài)庫為所有程序都可使用秤茅,在運行時由對應(yīng)的進(jìn)程映射、加載到自己的內(nèi)存空間
所以動態(tài)鏈接庫的內(nèi)容童叠,只是在編譯時參與鏈接框喳,它的數(shù)據(jù)則不會被合并到目標(biāo)APK中
例如:
? ?libs: ["ims-common"],
轉(zhuǎn)換成build.gradle
compileOnly files('../libs/ims-common.jar')
五.移植整體流程概述及思路
1.需要完成的前置工作
首先環(huán)境,最好用我上面的AndroidStudio版本及gradle配置
將代碼整編得到out產(chǎn)物
2.移植的基本思路和步驟
分析android.bp和AndroidManifest.xml文件,了解Settings帖努、SettingsLib等依賴情況撰豺、包名粪般、版本號等重要信息
根據(jù)AndroidManifest.xml文件獲得包名拼余,創(chuàng)建同名的AS項目或者模塊
根據(jù)android.bp分析對應(yīng)的build.gradle內(nèi)容
根據(jù)android.bp的依賴配置,到out目錄下復(fù)制對應(yīng)的名稱classes.jar亩歹,重命名后復(fù)制到libs目錄下
根據(jù)android.bp的依賴配置匙监,補全其他可從網(wǎng)絡(luò)獲取的依賴,如:androidx依賴小作、zxing依賴
解決其他模塊的編譯錯誤亭姥、依賴問題、并編譯通過
解決SettingsLib模塊的編譯錯誤顾稀、依賴問題达罗,并編譯通過
解決Settings模塊的編譯錯誤、依賴問題静秆,并編譯通過
解決Settings.app模塊的編譯錯誤粮揉,特別是依賴問題,有依賴缺失抚笔、依賴沖突是主要問題
對Settings.app模塊進(jìn)行簽名扶认、運行到設(shè)備上,解決運行時錯誤殊橙,驗證各個主要菜單功能正常辐宾,不發(fā)生閃退、崩潰
搞定E蚵5啤!
六.創(chuàng)建一個與Settings同包名的AS項目
1.AS創(chuàng)建新項目
2.選擇[No Activity]
3.填寫包名敞葛,完成創(chuàng)建
Name:Settings
Package name:com.android.settings
最后誉察,點擊【Finish】
4.刪除新建的Settings AS項目中的src與res目錄
刪除后的目錄結(jié)構(gòu)如下
.
├── app
│?? ├── build.gradle
│?? ├── libs
│?? ├── proguard-rules.pro
│?? └── src
│?????? ├── androidTest(刪除)
│?????? │?? └── java(刪除)
│?????? ├── main(保留目錄)
│?????? │?? ├── AndroidManifest.xml(用source_org/Settings 目錄下的同名文件覆蓋)
│?????? │?? ├── java(保留目錄)
│?????? │?? └── res(保留res目錄,刪除其目錄下的所有文件)
│?????? └── test(刪除)
│?????????? └── java(刪除)
├── build.gradle
├── gradle
│?? └── wrapper
│?????? ├── gradle-wrapper.jar
│?????? └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
12directories,?11files
5.將原版的Settings中src制肮、res冒窍、libs、AndroidManifest.xml文件復(fù)制到AS相應(yīng)目錄下(這一步可以放到最后和添加Settings.gradle的依賴一起做)
如下圖內(nèi)容復(fù)制到AndroidStudio的Settings對應(yīng)目錄下面
復(fù)制后對應(yīng)的Settings項目中如下:
注意values可以按照需要保存相應(yīng)的文件夾豺鼻,我這邊是只保留默認(rèn)的values和中文的values的
其實這些步驟也可以放到最后將所有模塊導(dǎo)入差不多了在做Settings模塊综液,不然會有很多報錯,這里我暫時不說Settings的gradle配置的了儒飒,這些都放到最后來說
七.移植SettingsLib模塊
1.創(chuàng)建New Module
2.選擇Android Library類型谬莹,填寫包名com.android.settingslib,模塊名:SettingsLib
然后點擊Finish
3.將原版的文件和配置移植到SettingsLib中
和Settings一樣,將res附帽,src埠戳,xml移植到SettingsLib中
找到原版的SettingsLib的位置
位置:\QCM6125_Android13.0_R04_r020\QSSI.13\frameworks\base\packages\SettingsLib
然后將目錄的內(nèi)容移植到SettingsLib中
然后分析Android.bp文件,將依賴配置添加到SettingsLib的gradle中蕉扮,最終效果如下圖: