【AOSP 应用集成全方案】

Android 系统应用构建指南:android_app 与 app_import

📋 目录

  • [APK 构建方式对比表](#APK 构建方式对比表)
  • [android_app:源码编译生成 APK](#android_app:源码编译生成 APK)
  • [app_import:导入预编译 APK](#app_import:导入预编译 APK)
  • 总结

APK 构建方式对比表

应用类型 预编译(已有APK) 源码编译(有源码)
普通系统应用 /system/app ③ app_import ① android_app
特权应用 /system/priv-app ④ app_import + privileged ② android_app + privileged
预编译(Android.mk) BUILD_PREBUILT ⑤ 旧写法 ---
可卸载预装 用户可卸载 ⑥ 装到 /data ⑥ 装到 /data

说明:

  1. android_app:用于从源码编译生成 APK
  2. app_import:用于导入预编译的 APK 文件
  3. privileged:标记应用为特权应用,可访问系统级 API
  4. 旧写法 :指 Android.mk 中的 BUILD_PREBUILT 方式
  5. 装到 /data:表示应用安装在用户数据分区,用户可卸载

**本文只简单讲解 android_app 和 app_import **

源码:AOSP 12

设备:Piexel 3

android_app源码编译生成-apk

在packages/apps/创建HelloWorld文件夹,然后分别创建 res和 src 两个子文件夹,目录结构如下

Android.bp文件

bash 复制代码
android_app {
    name: "HelloWorld",

    srcs: ["src/**/*.java"],
    resource_dirs: ["res"],

    certificate: "platform",         // platform 密钥签名
		// 或 presigned: true,          // 保留原签名
		
    // 使用公开 API 方法
    sdk_version: "current",
    //platform_apis: true,        或用 platform API,可访问 hidden 资源

    // 不是特权应用,装到 /system/app/
    // (不写 privileged: true 就是普通系统应用)

    // 依赖的静态库(如果不需要可以不写)
    // static_libs: ["androidx.appcompat_appcompat"],
}

AndroidManifest.xml 与普通 Android 应用没有区别

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworld">

    <application
        android:label="HelloWorld"
        android:icon="@mipmap/ic_launcher"
        android:supportsRtl="true">

        <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>
        </activity>

    </application>
</manifest>

MainActivity.java

java 复制代码
package com.example.helloworld;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

packages/apps/HelloWorld/res/values/strings.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">HelloWorld</string>
    <string name="hello_message">Hello World! 我是源码编译的系统应用</string>
</resources>

packages/apps/HelloWorld/res/layout/activity_main.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_message"
        android:textSize="24sp" />

</LinearLayout>

packages/apps/HelloWorld/res/mipmap-hdpi ,这里的图片我从 demo 复制的 使用的 webp格式

编译源码生成apk

apk 产物在

bash 复制代码
# 如果这里报错一般是源码错误
m HelloWorld 
# 确认产物存在
ls out/target/product/blueline/system/app/HelloWorld/

执行增量编译后,将 system.img刷入设备重启即可

app_import导入预编译-apk

目录结构如下:

Android.bp

android_app_import {

name: "test",

apk: "app.apk",

certificate: "platform",

privileged: true,

required: "privapp_whitelist_test",

}

// 白名单文件,编译后会被复制到 /system/etc/permissions/

prebuilt_etc {

name: "privapp_whitelist_firstinstalltime",

sub_dir: "permissions",

src: "privapp-permissions-firstinstalltime.xml",

filename: "privapp-permissions-firstinstalltime.xml",

}

预编译的是系统特权 app,我只在 demo 的清单文件 AndroidManifest.xml加了android:sharedUserId="android.uid.system"

xml 复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:sharedUserId="android.uid.system">
编译
bash 复制代码
m test

随后增量编译 刷入 system.img镜像到设备即可

相关推荐
方白羽7 小时前
Android Gradle 缓存与文件目录深度解析
android·gradle·android studio
曲幽11 小时前
Termux里的二进制和脚本,到底怎么运行才不踩坑?Termux-service 保活妙招!
android·termux·nohup·services·wake-lock
plainGeekDev12 小时前
单例模式 → object 声明
android·java·kotlin
程序员陆业聪12 小时前
读者点单·03|Compose 与传统 View 混用的 12 个真实坑
android
程序员陆业聪13 小时前
读者点单·02|Android 启动优化实战:Trace 抓取→Application 编排→冷启动全流程拆解
android
Coffeeee13 小时前
帮你快速理解AI Agent之我想招个Android实习生
android·人工智能·agent
恋猫de小郭14 小时前
苹果 AirPods 协议,Android 也可以使用完整版 AirPods 能力
android·前端·flutter
黄林晴14 小时前
告别无效重建:Gradle 9.6.0 解决 CI 构建缓存失效痛点告别无效重建:Gradle 9.6.0 解决 CI 建筑缓存失效痛点
android·gradle
张风捷特烈15 小时前
Flutter 类库大揭秘#01 | path_provider架构与设计
android·flutter
_阿南_1 天前
Android文件读写和分享总结
android