Aosp源码上手攻略目录:

  • Android13 源码下载与编译
  • Android13 增加 Product
  • Android13 自界说模块增加
  • Android13 预编译模块增加
  • Android13 App 预装详解

1. 在体系中集成已编译好的 apk

1.1 不行卸载的apk

不行卸载的 apk 一般是体系类运用,用于保证产品的根底功用体会例如 电话 短信 日历 运用商店 浏览器等

Android Studio 新建一个 Empty Activity 项目 TestApp,编译出 Debug Apk包,重命名为 testapp.apk

device/Jelly/Rice14/prebuilt/apks 目录下创立如下的文件与目录:

testapp/
├── Android.bp
└── testapp.apk

其间 testapp.apk 是咱们运用 Android Studio 打包好的 apk 包,Android.bp 的内容如下:

android_app_import {
    name: "testapp",
    //是否为特权运用 
    privileged: false,
    //运用本来的签名
    presigned: true,
    apk: "testapp.apk",
    //安装到 product 分区
    product_specific: true,
}

然后修正 device/Jelly/Rice14/Rice14.mk 文件内容,将 testapp 模块增加到产品中:

PRODUCT_PACKAGES += hello \
	libmytriangle \
	trianglemain \
	busybox \
	mymathmain \
	testapp \

接下来,编译项目,发动虚拟机:

source build/envsetup.sh
lunch Rice14-eng
make -j16
emulator

然后再模拟器中就可以找到咱们的 testapp 了:

Android13 App 预装详解

打开 testapp:

Android13 App 预装详解

也可以运用 Android.mk 来集成:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := testapp
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_SRC_FILES := testapp.apk
LOCAL_MODULE_CLASS := APPS
#LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
include $(BUILD_PREBUILT)

以上内容触及到了 体系App、体系特权App以及体系签名等概念,这儿有个形象即可,后面会有单独的文章做详细的说明。

1.2 可卸载的 apk

这类 apk 一般是厂商预装好的一些第三方运用。

这部分内容触及到了 selinux 与体系发动相关的常识,在解说完这两部分常识后,咱们再回头解说该部分内容。

1.3 可卸载但康复出厂设置又康复的 apk

这类 apk 一般是一些次重要的厂商 app,例如厂商自己的论坛,商城,智能硬件等 app,假如第三方厂商给得足够多,也可以将其配置为可卸载但康复出厂设置又康复的 apk。

这部分内容触及到了 selinux 与体系发动相关的常识,在解说完这两部分常识后,咱们再回头解说该部分内容。

2. 在体系中集成App源码

2.1 简略 App 源码的增加

运用 Android Studio 新建一个空项目 SourceApp,语言选择 Java。创立完成后,将项目移动到 aosp/device/Jelly/Rice14 目录下。在项目的根目录下增加 Android.bp 文件:

android_app {
    name: "SourceApp",
    srcs: ["app/src/main/java/**/*.java"],
    sdk_version: "current",
    //LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    certificate: "platform",
    // 指定Manifest文件
    manifest: "app/src/main/AndroidManifest.xml",
    resource_dirs: ["app/src/main/res"],
    //依靠
    static_libs: ["androidx.appcompat_appcompat",
                  "androidx.recyclerview_recyclerview",
                 "com.google.android.material_material",
                 "androidx-constraintlayout_constraintlayout"],
}

修正 app/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.yuandaima.sourceapp">
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SourceApp"
        tools:tar getApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>
</manifest>

修正的当地只有一个:给 manifest 节点增加了 package 属性

接下来编译体系,发动虚拟机就可以看到咱们的 SourceApp 了

source build/envsetup.sh
lunch Rice14-eng
make -j16
emulator

Android.bp 中咱们增加了许多依靠:

static_libs: ["androidx.appcompat_appcompat",
                  "androidx.recyclerview_recyclerview",
                 "com.google.android.material_material",
                 "androidx-constraintlayout_constraintlayout"],

这些依靠模块开始界说在 SourceApp 的 build.gradle 中:

dependencies {
    implementation 'androidx.appcompat:appcompat:1.6.0'
    implementation 'com.google.android.material:material:1.7.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    //测验相关的库暂时不用管
}

在 AOSP 中, google 供给的库和第三方供给的常用库均以预编译模块的方式界说在 prebuilt 目录下。比方常用的 AndroidX 库界说在 sdk/current/androidx 目录下:

~/aosp/prebuilts/sdk/current/androidx$ ls
Android.bp  JavaPlugins.bp  m2repository  manifests

jar aar 库以模块的形式引进编译体系,这些模块就界说在上面的 Android.bp 中。比方 recyclerview 库的界说如下:

android_library {
    name: "androidx.recyclerview_recyclerview",
    sdk_version: "31",
    apex_available: [
        "//apex_available:platform",
        "//apex_available:anyapex",
    ],
    min_sdk_version: "14",
    manifest: "manifests/androidx.recyclerview_recyclerview/AndroidManifest.xml",
    static_libs: [
        "androidx.recyclerview_recyclerview-nodeps",
        "androidx.annotation_annotation",
        "androidx.collection_collection",
        "androidx.core_core",
        "androidx.customview_customview",
    ],
    java_version: "1.7",
}

当咱们的体系运用需要引证一个库时,咱们应该首先考虑在 prebuilt 目录下运用 find grep 指令查找。当咱们需要的库不存在时再自行引进相关的库。

2.2 App 增加第三方依靠

在 App 的开发过程中,咱们常常会引进一些第三方库,这些库可以分为以下三类:

  • jar
  • aar
  • so

jar 包的引进

在Android13 预编译模块增加中咱们增加了一个 jar 库:

java_import {
    name: "libmytriangle",
    host_supported: true,
    installable: false,
    jars: ["javalib.jar"],
}

上一节引进的 App, 稍作修正即可引进这个 jar 包:

android_app {
    name: "SourceApp",
    srcs: ["app/src/main/java/**/*.java"],
    sdk_version: "current",
    //LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    certificate: "platform",
    // 指定Manifest文件
    manifest: "app/src/main/AndroidManifest.xml",
    resource_dirs: ["app/src/main/res"],
    //依靠
    static_libs: ["androidx.appcompat_appcompat",
                  "androidx.recyclerview_recyclerview",
                 "com.google.android.material_material",
                 "androidx-constraintlayout_constraintlayout"],
    libs: [
        	"libmytriangle",
    	],
}

这儿的 static_libs 和 libs 可能有点难以区别,看看文档怎样说的:

libs list of string , list of java libraries that will be in the classpath

static_libs list of string , list of java libraries that will be compiled into the resulting jar

翻译一下便是 libs 引进的库会被增加到 classpath 环境变量中,static_libs 引进的库会打包到终究的产品中

aar包的引进

假设咱们的 SourceApp 需要引进 lottie 这个动画库。

首先咱们这儿下载好 lottie 库的 aar 打包文件。

device/Jelly/Rice14 目录下创立如下的目录结构:

liblottie/
├── Android.bp
└── lottie-5.2.0.aar

其间 Android.bp 的内容如下:

android_library_import {
    name: "lib-lottie",
    aars: ["lottie-5.2.0.aar"],
    sdk_version: "current",
}

然后咱们修正 SourceApp 中的 Android.bp:

    static_libs: ["androidx.appcompat_appcompat",
                  "androidx.recyclerview_recyclerview",
                 "com.google.android.material_material",
                 "androidx-constraintlayout_constraintlayout",
                 "lib-lottie"],

这样就导入好了 lottie 库

so包的引进

在Android13 预编译模块增加中咱们增加了一个 so 库:

cc_prebuilt_library_shared {
    name: "libmymath",
     arch: {
        x86_64: {
            srcs: ["libmymath.so"],
        },
    },
    export_include_dirs: ["."],
    compile_multilib: "64",
    //注释掉
    //product_specific: true,
    // product_available: true, 才干被咱们的 app 引证
    product_available: true,
}

咱们修正 SourceApp 中的 Android.bp 引进 so 库:


android_app {
    name: "SourceApp",
    ......
     jni_libs: [
        "libmymath",
	]
     //product_specific: true 才干引证到咱们的 so 库
     product_specific: true,
}

2.3 App 含有 jni native 代码

这个可以参阅源码中的 development/samples/SimpleJNI :

.
├── Android.bp
├── AndroidManifest.xml
├── jni
│   ├── Android.bp
│   └── native.cpp
└── src
    └── com
        └── example
            └── android
                └── simplejni
                    └── SimpleJNI.java

其间 jni/Android.bp:

package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_library_shared {
    name: "libsimplejni",
    // All of the source files that we will compile.
    srcs: ["native.cpp"],
    // All of the shared libraries we link against.
    shared_libs: ["liblog"],
    // No static libraries.
    static_libs: [],
    cflags: [
        "-Wall",
        "-Werror",
    ],
    header_libs: ["jni_headers"],
    stl: "none",
    sdk_version: "current",
}

Android.bp 的内容如下:

package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}
android_app {
    name: "SimpleJNI",
    srcs: ["**/*.java"],
    jni_libs: ["libsimplejni"],
    optimize: {
        enabled: false,
    },
    sdk_version: "current",
    dex_preopt: {
        enabled: false,
    },
}

参阅资料

  • android体系源码中增加app源码(源码布置移植)
  • AOSP 预置 APP
  • Android Framework 常见解决方案(15)android内置可卸载APP集成方案
  • Android Framework 常见解决方案(02)android体系级APP集成方案
  • 在AOSP编译时,增加预编译apk
  • Android体系预制可自由卸载apk
  • Soong Modules Reference
  • Jetpack太香了,体系App也想用,怎样办?
  • Android.bp 文件中引进aar、jar、so库正确编译方法(值得收藏)