Bootstrap

AS编译系统应用

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 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')
            }
        }
    }
}

引用:使用 AS 开发 System App - 小专栏

注:

还可以从这里直接下载Android studio中用的库

https://mvnrepository.com/ 从这里可以查找Android studio用的库

下载的时候将前面的网址换一些就可以下载了,如:

https://maven.google.com/com/android/support/constraint/constraint-layout/2.0.4/constraint-layout-2.0.4.aar

https://dl.google.com/dl/android/maven2/com/android/support/constraint/constraint-layout/2.0.4/constraint-layout-2.0.4.aar

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

;