AS编译系统应用 三部曲:
一、生成系统签名
二、导入源码,用gradle配置
三、配置依赖jar包
一、生成系统签名
1、生成签名
部分的系统 App 有在 Manifest 中加入了 sharedUserId 标签:
android:sharedUserId="android.uid.systemui"
此时如果 APK 没有当前系统的签名,是无法安装和使用的,因此需要获取得到系统的签名。
在源码的 build\target\product\security 目录下,可以得到 platform.pk8 和 platform.x509.pem 两个文件,我们需要根据如下指令,或生成 keystore 文件。将这两个文件放在一个目录下。在 Linux 或 Mac 下依次执行以下指令:
得到 platform.priv.pem:
openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.priv.pem -nocrypt
得到 platform.pk12:
openssl pkcs12 -export -in platform.x509.pem -inkey platform.priv.pem -out platform.pk12 -name [别名]
此过程提示输入密码,密码在下一步时使用。
生成 keystore
keytool -importkeystore -deststorepass [密码] -destkeypass [别名密码] -destkeystore [名称.keystore] -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass [密码] -alias [别名]
以上命令均需要将“[xxx]”替换成对应的信息,建议密码全部设置成一样的,执行完毕,即可得到keystore文件。
模拟器的签名和默认系统源码使用的签名是一致的,因此从官方源码下载的这两个文件生成的签名,可作为系统签名在模拟器上使用。
2、gradle应用签名文件
app/build.gradle 新增如下配置:
dexOptions {
preDexLibraries true
maxProcessCount 8
}
// 使用 Java 8
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// 签名信息
signingConfigs {
release {
keyAlias '别名'
keyPassword '别名密码'
storeFile file('../xxx.keystore')
storePassword '密码'
}
}
// 构建类型引用签名文件
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
// 加快速度
ext.enableCrashlytics = false
ext.alwaysUpdateBuildId = false
aaptOptions {
cruncherEnabled false
}
signingConfig signingConfigs.release
}
}
// 可能有些不影响运行的构建错误,这里忽略即可
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.support:preference-v7:27.1.1'
implementation 'com.android.support:mediarouter-v7:27.1.1'
implementation 'com.android.support:palette-v7:27.1.1'
implementation 'com.android.support:preference-v14:27.1.1'
implementation 'com.android.support:leanback-v17:27.1.1'
}
二、导入源码,用gradle配置
导入源码
1、创建的Project包名要是系统应用包名
2、gradle引用源码:
app/build.gradle 添加
文件夹名字.srcDirs
android {
...
sourceSets {
main {
res.srcDirs = [
'src/main/res',
]
java.srcDirs = [
'src/main/java',
]
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
三、导入jar依赖
1、查找对于依赖包
https://developer.android.com/topic/libraries/support-library/revisions
https://developer.android.com/topic/libraries/support-library/rev-archive
需要 fq,或者把网址改成:Android 移动应用开发者工具 – Android 开发者 | Android Developers
从Android studio 的库 转 源码库:
在这里找:
prebuilts/sdk/update_prebuilts.py
一些三方的库可以像dialer里这样将jar包当做三方库引入,或者将jar包编译成模块引入:
这些jar包放在源码的prebuilts/tools/common/m2/repository 下
/external/kotlinc/lib/kotlin-stdlib-jdk8.jar
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
dialer-auto-value:../../../prebuilts/tools/common/m2/repository/com/google/auto/value/auto-value/1.5.2/auto-value-1.5.2.jar \
dialer-dagger2-compiler:../../../prebuilts/tools/common/m2/repository/com/google/dagger/dagger-compiler/2.7/dagger-compiler-2.7.jar \
dialer-dagger2:../../../prebuilts/tools/common/m2/repository/com/google/dagger/dagger/2.7/dagger-2.7.jar \
dialer-dagger2-producers:../../../prebuilts/tools/common/m2/repository/com/google/dagger/dagger-producers/2.7/dagger-producers-2.7.jar \
include $(BUILD_HOST_PREBUILT)
# Enumerate target prebuilts to avoid linker warnings like
# Dialer (java:sdk) should not link to dialer-guava (java:platform)
include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE := dialer-guava-target
LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := ../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/23.0/guava-23.0.jar
LOCAL_UNINSTALLABLE_MODULE := true
include $(BUILD_PREBUILT)
2、
那么如何检测缺失的依赖呢?其实很简单,通过 Build -> Rebuild Project,或者 Make Project,或者选中 Module 进行 Make Module ‘xxx’ 都可以。
3、
通常来说,系统 App 总是会依赖 framework.jar,android-common.jar,telephony-common.jar,core.jar 等,这些 jar 都能在 out 目录中找到
4、jar的编译顺序
项目根目录的 build.gradle 中增加如下配置:
allprojects {
...
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
// 如果有多个jar需要提升优先级,用分号隔开,比如:jar/framework.jar;jar/core-all.jar;
options.compilerArgs.add('-Xbootclasspath/p:jar/framework.jar;')
}
}
}
然后在需要引用这个 jar 的 Module 中去引用即可:
compileOnly files('../jar/framework.jar')
implementation 会在打包 apk 时,把 jar 里面的资源也一起打入 apk 中,compileOnly 的方式只是在编译时使用,而不会打包到 apk 中,因为我们使用的这个 jar,在 8.1 的系统上已经内置了,它不像 support 库那样是需要带进 apk 的。
提升 framework.jar 等 jar 包的优先级后,在 Linux 或 Mac 下会发现编译不过,而在 Windows 下可以,那是因为类 Unix 系统的分隔符和 Windows 的不一样,可以在根目录的 build.gradle 做如下判断:
allprojects {
repositories {
google()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
if (isWindows()) {
options.compilerArgs.add('-Xbootclasspath/p:' +
'jar/framework.jar;' +
'jar/core_oj.jar;' +
'jar/telephony-common.jar;' +
'jar/android-common.jar')
} else {
options.compilerArgs.add('-Xbootclasspath/p:' +
'./jar/framework.jar:' +
'./jar/core_oj.jar:' +
'./jar/telephony-common.jar:' +
'./jar/android-common.jar')
}
}
}
}
注:
还可以从这里直接下载Android studio中用的库
https://mvnrepository.com/ 从这里可以查找Android studio用的库
下载的时候将前面的网址换一些就可以下载了,如:
https://dl.google.com/dl/android/maven2
二、Android studio 工程转系统编译:
1、如上3.1中将studio中的库转正系统中的名字,有一些AAR的库需要处理:
#LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
LOCAL_DEX_PREOPT := false
LOCAL_SRC_FILES := $(call all-java-files-under, app/src/main/java)
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/src/main/res
LOCAL_ASSET_DIR := $(LOCAL_PATH)/app/src/main/assets
LOCAL_PREBUILT_JNI_LIBS:= \
app/src/main/libs/arm64-v8a/libbarcodereaderCam2.so \
app/src/main/libs/arm64-v8a/libbarcodereaderCam2-4100.so \
app/src/main/libs/arm64-v8a/libbarcodereaderCam2_0301.so \
app/src/main/libs/arm64-v8a/libIAL.so \
app/src/main/libs/arm64-v8a/libSDL.so
LOCAL_STATIC_ANDROID_LIBRARIES := \
$(ANDROID_SUPPORT_DESIGN_TARGETS) \
androidx.core_core \
com.google.android.material_material \
androidx.cardview_cardview \
androidx.recyclerview_recyclerview \
androidx.appcompat_appcompat \
androidx.annotation_annotation
LOCAL_STATIC_JAVA_LIBRARIES := \
xxx
#LOCAL_STATIC_JAVA_AAR_LIBRARIES:= myworkmanager_work
LOCAL_AAPT_FLAGS := \
--auto-add-overlay
# --extra-packages androidx.work
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/system/app
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
xxx:libs/vendor.fpsensor.hardware.fpsensorhidlsvc-V2.0-java.jar \
myworkmanager_work:../../../../../prebuilts/maven_repo/android/android/arch/work/work-runtime/1.0.0-alpha04/work-runtime-1.0.0-alpha04.aar
#:libs/workmanagerruntime.jar
#myworkmanager_work:../../../../../prebuilts/maven_repo/android/android/arch/work/work-runtime/1.0.0-alpha02/work-runtime-1.0.0-alpha02-sources.jar
include $(BUILD_MULTI_PREBUILT)
#include $(CLEAR_VARS)
#LOCAL_MODULE_CLASS := JAVA_LIBRARIES
#LOCAL_MODULE := myworkmanager
#LOCAL_SDK_VERSION := current
#LOCAL_SRC_FILES := ../../../../../prebuilts/maven_repo/android/android/arch/work/work-runtime/1.0.0-alpha04/work-runtime-1.0.0-alpha04.aar
#LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
#LOCAL_BUILT_MODULE_STEM := javalib.jar
#include $(BUILD_PREBUILT)
2、AndroidManifest.xml
application
.....................
...........................
tools:replace="android:appComponentFactory"
android:appComponentFactory="androidx.core.app.AppComponentFactory"
>
3、还有一些运行时的兼容问题
要把所以support包替换成AndroidX 然后在out中清除cache