一.环境准备

首先需要特定版本的AndroidStudio,由于AndroidStudio与gradle版本相关联,所以也需要注意gradle版本,如下是我的AndroidStudio与gradle版本

001 Android13将Settings移植到AndroidStudio中(一)_android


在gradle-wrapper.properties中配置gradle版本如下:

#Sun Aug 22 14:48:51 CST 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中gradle配置如下:

// 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版本可以进行下载,不用卸载原先的AndroidStudio,是可以运行多个不同版本的AndroidStudio的,AndroidStudio下载地址:Android Studio 下载文件归档  |  Android 开发者  |  Android Developers

Java版本如下:

001 Android13将Settings移植到AndroidStudio中(一)_Android_02


二.理解Settings Android.bp文件里面的依赖关系

首先我们找到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",                 //此模块是调用命令,生成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相关内容

android_library {               //此模块是生成一个JAR LIBRARY

name: "Settings-core",      //生成的模块名称为:Settings-core

platform_apis: true,        //获取访问@hide API的权限,谷歌发布的SDK是不包含隐藏API的

defaults: [

"SettingsLibDefaults",      //使用名为SettingsLibDefaults的模块defaults配置,从名字得知还需要引入SettingsLib相关模块

"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   模块依赖的动态库列表

"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,  //授权使用@hide API

certificate: "platform",  //采用系统签名    

system_ext_specific: true,       //结合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"],         //静态依赖于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"],

}

分析结果:

1.生成Settings.apk的android_app编译配置,通过Settings-core间接依赖于srcs:["src/**/*java"]

  • 所以未直接使用自己目录下的源码来生成
  • 若依照此配置构建AS工程,则工程中没有Settings源码,而是由各种库组成
  • 我们构建AS工程,本身是为了调试Settings源码,所以jar就失去了构建AS工程的意义
  • 结论:我们构建的Settings AS工程,其Settings.app的build.gradle将直接依赖源码,而不是Settings-core.jar

2.从Settings-core模块的defaults应用得知,我们还需要依赖模块:SettiingsLibDefaults和SettingsLib-search-defaults

  • 从后续SettingsLib的依赖分析得知,Settings需要依赖于SettingsLib,所以我们还得继续分析SettingsLib的Android.bp

3.以androidx开头的,均为安卓的支持库,通过Maven远程仓库获取

三.理解SettingsLib中的Android.bp文件中依赖关系

上面说了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: [  //静态依赖,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"模块默认引用的一组名为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"

],

}

分析结果

1.因为"Settings-core"模块默认引用的一组名为"SettingsLibDefaults"的配置,所以我们需要先解决"SettingsLibDefaults"

2.通过对"SettingsLibDefaults"分析,我们得知,需要引入"SettingsLib"的模块,此模块负责编译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仓获取。

四.静态库与动态库的依赖方式

1.静态链接库:static_libs

静态库特点:

  • 每一个被static_libs命名的模块,他的数据都会被合并到目标apk中
  • 同时,这些static_libs还将承担编译时被引用符号的解析工作

例如:

    static_libs: ["android.hardware.dumpstate-V1.1-java"],

转换成build.gradle:

implementation files('../libs/android.hardware.dumpstate-V1.1-java.jar')

2.动态库链接:shared_libs、libs

  • 与静态链接库的区别,动态库为所有程序都可使用,在运行时由对应的进程映射、加载到自己的内存空间
  • 所以动态链接库的内容,只是在编译时参与链接,它的数据则不会被合并到目标APK中

例如:

   libs: ["ims-common"],

转换成build.gradle

compileOnly files('../libs/ims-common.jar')

五.移植整体流程概述及思路

1.需要完成的前置工作

  • 首先环境,最好用我上面的AndroidStudio版本及gradle配置
  • 将代码整编得到out产物

2.移植的基本思路和步骤

  • 分析android.bp和AndroidManifest.xml文件,了解Settings、SettingsLib等依赖情况、包名、版本号等重要信息
  • 根据AndroidManifest.xml文件获得包名,创建同名的AS项目或者模块
  • 根据android.bp分析对应的build.gradle内容
  • 根据android.bp的依赖配置,到out目录下复制对应的名称classes.jar,重命名后复制到libs目录下
  • 根据android.bp的依赖配置,补全其他可从网络获取的依赖,如:androidx依赖、zxing依赖
  • 解决其他模块的编译错误、依赖问题、并编译通过
  • 解决SettingsLib模块的编译错误、依赖问题,并编译通过
  • 解决Settings模块的编译错误、依赖问题,并编译通过
  • 解决Settings.app模块的编译错误,特别是依赖问题,有依赖缺失、依赖冲突是主要问题
  • 对Settings.app模块进行签名、运行到设备上,解决运行时错误,验证各个主要菜单功能正常,不发生闪退、崩溃
  • 搞定!!!

六.创建一个与Settings同包名的AS项目

1.AS创建新项目

001 Android13将Settings移植到AndroidStudio中(一)_android_03

2.选择[No Activity]

001 Android13将Settings移植到AndroidStudio中(一)_java_04

3.填写包名,完成创建

Name:Settings

Package name:com.android.settings

最后,点击【Finish】

001 Android13将Settings移植到AndroidStudio中(一)_android_05

4.删除新建的Settings AS项目中的src与res目录

删除后的目录结构如下

.

├── 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


12 directories, 11 files


5.将原版的Settings中src、res、libs、AndroidManifest.xml文件复制到AS相应目录下(这一步可以放到最后和添加Settings.gradle的依赖一起做)

如下图内容复制到AndroidStudio的Settings对应目录下面

001 Android13将Settings移植到AndroidStudio中(一)_java_06

复制后对应的Settings项目中如下:

001 Android13将Settings移植到AndroidStudio中(一)_Android_07

001 Android13将Settings移植到AndroidStudio中(一)_Android_08

注意values可以按照需要保存相应的文件夹,我这边是只保留默认的values和中文的values的

其实这些步骤也可以放到最后将所有模块导入差不多了在做Settings模块,不然会有很多报错,这里我暂时不说Settings的gradle配置的了,这些都放到最后来说


七.移植SettingsLib模块

1.创建New Module

001 Android13将Settings移植到AndroidStudio中(一)_Android_09

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

001 Android13将Settings移植到AndroidStudio中(一)_Android_10

然后将目录的内容移植到SettingsLib中

然后分析Android.bp文件,将依赖配置添加到SettingsLib的gradle中,最终效果如下图:


001 Android13将Settings移植到AndroidStudio中(一)_android_11

001 Android13将Settings移植到AndroidStudio中(一)_Android_12

001 Android13将Settings移植到AndroidStudio中(一)_java_13

后续完整内容请关注微信公众号:

001 Android13将Settings移植到AndroidStudio中(一)_java_14