以下内容参考小专栏SystemApp系列
教程实现,亲测OK。这里只讲个基本流程,不讲原理,如果你无法成功导入建议参考这个小专栏SystemApp系列 (非广告,确实不错的文章),这个系列的教程会从原理上讲解,非常详细,内容基于Android8.0。
首先你需要会Android Studio的基本使用,这部分内容在这个基础上介绍一些新的使用技巧,为后续内容奠定基础
注意:
对于资源文件:当A路径和B路径下同时包含一个同名文件,会进行合并
对于java文件:当A路径和B路径下同时包含一个同名文件,会优先使用第一个路径下的
文件:app/buid.gradle
android {
.....
sourceSets {
main {
res.srcDirs = [
'src/main/res', //原本的资源文件路径
'../SystemUI_SRC/res', //新增的资源文件路径
]
java.srcDirs = [
'src/main/java', //原本的代码路径
'../SystemUI_SRC/src', //新增的代码路径
'../car-lib/src',
'../car-lib/src_feature_current',
]
manifest.srcFile '../SystemUI_SRC/AndroidManifest.xml' //指定AndroidManifest.xml文件路径
}
}
文件:build.gradle
allprojects {
......
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
// 如果有多个jar包,用分号隔开
options.compilerArgs.add('-Xbootclasspath/p:jar/framework.jar;jar/core-oj.jar')
}
}
}
包名.R
,由此可见,当SystemUI依赖的库包含资源文件时,需要单独为其创建一个Module,否则无法找到id选择No Activity就行
包名:com.android.systemui
类型为Android Library,
需要创建四个模块,为什么是这四个,可以看SystemUI的Android.mk和源码下的AndroidManifest.xml文件的个数,一个AndroidManifest.xml文件需要新建一个模块
模块名 | 包名 |
---|---|
keyguard | com.android.keyguard |
plugin | com.android.systemui.plugins |
shared | com.android.systemui.shared |
settingslib | com.android.settingslib |
test
和androidTest
目录,我们不需要这些//文件:gradle.properties
android.useAndroidX=false
android.enableJetifier=false
这一步本来应该一步一步来的,缺啥拷啥,最后编译成功。为了节省大家时间我把需要拷贝的所有文件一次性列出来了
源文件 | 目标路径(相对于项目根目录) |
---|---|
frameworks/base/packages/SystemUI | SystemUI_SRC |
frameworks/base/packages/SettingsLib | SettingsLib_SRC |
packages/services/Car/car-lib | car-lib |
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar | jar/framework.jar |
out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes-header.jar | jar/telephony-common.jar |
out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar | jar/core-libart.jar |
out/target/common/obj/JAVA_LIBRARIES/core-oj_intermediates/classes.jar | jar/core-oj.jar |
下面这部分文件是aidl,proto,logtags文件生成的java文件,直接拷贝到新建的模块目录下。
源文件 | 目标路径(相对于项目根目录) |
---|---|
out/target/common/obj/JAVA_LIBRARIES/SystemUI-proto_intermediates/proto/src/* | app/src/main/java |
out/target/common/obj/JAVA_LIBRARIES/SystemUI-tags_intermediates/logtags/src/* | app/src/main/java |
out/target/common/obj/JAVA_LIBRARIES/android.car_intermediates/aidl/src/* | app/src/main/java |
out/target/common/obj/APPS/SystemUI_intermediates/aidl/src/* | app/src/main/java |
out/target/common/obj/JAVA_LIBRARIES/SystemUISharedLib_intermediates/aidl/src/* | shared/src/main/java |
这一步操作完后工程目录长这样:
systemuipliginlib
模块就是上面说的plugin模块,我自己起的名字不同而已。
keystore是签名文件,生成方式参考 :生成keystore,不用下载里面的文件, Linux上有这个命令,可以直接执行。
1.项目的build.gradle
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' } //加快下载
google()
}
.......
allprojects {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
google()
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
// 如果有多个jar需要提升优先级,用分号隔开
options.compilerArgs.add('-Xbootclasspath/p:jar/framework.jar;jar/core-oj.jar')
}
}
}
......
android {
compileSdkVersion 28 //必须是28(Android 9.0),其它模块也改成28
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "com.android.systemui"
minSdkVersion 28
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
.....
// 签名信息
signingConfigs {
release {
keyAlias 'konka'
keyPassword 'xxxx123'
storeFile file('../keystore/xxxx.platform.keystore')
storePassword 'xxxx123'
}
}
....
sourceSets {
main {
res.srcDirs = [
//'src/main/res',
'../SystemUI_SRC/res',
]
java.srcDirs = [
'src/main/java',
'../SystemUI_SRC/src',
'../car-lib/src',
'../car-lib/src_feature_current',
]
manifest.srcFile '../SystemUI_SRC/AndroidManifest.xml'
}
}
}
.....
dependencies {
compileOnly files('../jar/core-oj.jar')
compileOnly files('../jar/framework.jar')
compileOnly files('../jar/telephony-common.jar')
compileOnly files('../jar/core-libart.jar')
//需要那些依赖,可以在Android.mk里看到
//noinspection GradleCompatible
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:car:28.0.0-alpha5'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:preference-v7:28.0.0'
implementation 'com.android.support:mediarouter-v7:28.0.0'
implementation 'com.android.support:palette-v7:28.0.0'
implementation 'com.android.support:preference-v14:28.0.0'
implementation 'com.android.support:leanback-v17:28.0.0'
implementation 'com.android.support:gridlayout-v7:28.0.0-rc02'
implementation 'com.android.support:slices-builders:28.0.0-alpha3'
implementation 'com.android.support:slices-core:28.0.0-alpha3'
implementation 'com.android.support:slices-view:28.0.0-alpha3'
implementation 'com.google.protobuf:protobuf-java:3.12.2'
implementation group: 'com.google.protobuf.nano', name: 'protobuf-javanano', version: '3.1.0'
//把几个模块包含进来
implementation project(path: ':settingslib')
implementation project(path: ':plugin')
implementation project(path: ':shared')
implementation project(path: ':keyguard')
}
...
sourceSets {
main {
res.srcDirs = [
'src/main/res',
'../SystemUI_SRC/res-keyguard',
]
}
}
.....
dependencies {
}
sourceSets {
main {
java.srcDirs = [
'../SystemUI_SRC/plugin/src',
]
}
}
.....
dependencies {
compileOnly files('../jar/framework.jar')
}
sourceSets {
main {
java.srcDirs = [
'src/main/java',
'../SystemUI_SRC/shared/src',
]
}
}
.....
dependencies {
compileOnly files('../jar/framework.jar')
}
sourceSets {
main {
res.srcDirs = [
'src/main/res',
'../SettingsLib_SRC/res',
]
java.srcDirs = [
'src/main/java',
'../SettingsLib_SRC/src',
]
}
}
.......
dependencies {
compileOnly files('../jar/core-libart.jar')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:preference-v7:28.0.0'
implementation 'com.android.support:preference-v14:28.0.0'
}
//通过AndroidStudio的替换把下面内容替换为空就行
(.*?)(.*?) (.*?)
(.*?)(.*?) (.*?)
(.*?)\n(.*?)\n(.*?) (.*?)