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

一.环境准备

首先需要特定版本的AndroidStudio,由于AndroidStudio与gradle版本相关联,所以也需要注意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中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版本如下:

二.理解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创建新项目

2.选择[No Activity]


3.填写包名,完成创建

Name:Settings

Package name:com.android.settings

最后,点击【Finish】


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

12directories, 11files

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

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


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



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

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

七.移植SettingsLib模块

1.创建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


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

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



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容