Android 9.0 SystemUI导入Android Studio教程

以下内容参考小专栏SystemApp系列教程实现,亲测OK。这里只讲个基本流程,不讲原理,如果你无法成功导入建议参考这个小专栏SystemApp系列 (非广告,确实不错的文章),这个系列的教程会从原理上讲解,非常详细,内容基于Android8.0。

前提

  1. 需要整个系统源码
  2. 系统源码整编过一次(我们需要out目录下的一些文件)

Android Studio使用

首先你需要会Android Studio的基本使用,这部分内容在这个基础上介绍一些新的使用技巧,为后续内容奠定基础

  • gradle可以指定源码及资源目录的路径

注意:
对于资源文件:当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文件路径
        }
}
  • 可以设置jar包的优先级
文件:build.gradle
allprojects {
......
gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            // 如果有多个jar包,用分号隔开
            options.compilerArgs.add('-Xbootclasspath/p:jar/framework.jar;jar/core-oj.jar')
        }
    }
}
  • 资源文件索引方式
    代码中查找id都会导入包名.R,由此可见,当SystemUI依赖的库包含资源文件时,需要单独为其创建一个Module,否则无法找到id

创建AS项目

  1. 创建一个新的项目

选择No Activity就行
包名:com.android.systemui

  1. 创建Module

类型为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
  1. 删除不用的文件
    删除每个模块下的testandroidTest目录,我们不需要这些
    删除gradle – dependencies下的所有内容
  2. 关闭androidx
    //文件: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上有这个命令,可以直接执行。
Android 9.0 SystemUI导入Android Studio教程_第1张图片

配置项目

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')
        }
    }
}
......
  1. app模块的build.gradle
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')
}
  1. keyguard的build.gradle
    同样把sdkVersion都改为28,其它所有模块都这样改
...
sourceSets {
        main {
            res.srcDirs = [
                    'src/main/res',
                    '../SystemUI_SRC/res-keyguard',
            ]
        }
    }
    .....
   dependencies {
   } 
  1. plugin的build.gradle
sourceSets {
        main {
            java.srcDirs = [
                    '../SystemUI_SRC/plugin/src',
            ]
        }
    }
.....
dependencies {
    compileOnly files('../jar/framework.jar')
}
  1. shared
sourceSets {
        main {
            java.srcDirs = [
                    'src/main/java',
                    '../SystemUI_SRC/shared/src',
            ]
        }
    }
    .....
dependencies {
    compileOnly files('../jar/framework.jar')
} 
  1. settingslib的build.gradle
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'
}

资源文件编译问题

  1. strings.xml中重定义问题
    安卓源码的编译方式与AndroidStudio还是有些差异的;android源码可以通过product来选中使用哪个资源,而Android Studio不行,会出现重复定义的情况。
    需要删除strings.xml中包含product="tablet"的strings标签
//通过AndroidStudio的替换把下面内容替换为空就行
(.*?)(.*?)(.*?)
(.*?)(.*?)(.*?)
(.*?)\n(.*?)\n(.*?)(.*?)
  1. 编译时还会出现一些attr重复定义,strings.xml语法错误等,百度一下自己手动修改过来就行了

你可能感兴趣的:(android,android,studio,framework)