写给运用开发的 Android Framework 教程是一个系列教程,现在已更新以下内容:

  • Android Framework 学习路线攻略

  • 体系开发基础

    • Ubuntu 运用快速入门
    • Make 构建东西入门
    • 了解 Unicode UTF-8 UTF-16 UTF-32
    • Linux Shell 脚本编程入门——中心基础语法
    • SEAndroid 运用极速上手
    • 了解 C++ 的 Memory Order
  • AOSP 上手攻略

    • AOSP 极速上手
    • 体系开发东西引荐
    • 增加 Product
    • 增加 C/C++、Java 可履行程序
    • 增加 C/C++、Java 库
    • 增加装备文件与删去已有模块
    • 体系 App 源码增加
    • 运用 Android Studio 开发体系 App
    • 增加开机自启动 Shell 脚本
  • 学穿 Binder 系列

    • Binder 基本原理
    • Binder 程序示例之 C 语言篇
    • Binder 服务注册进程情形剖析之C语言篇
    • Binder 服务获取与运用进程情形剖析之C语言篇
    • Binder C++ 程序示例
    • Binder C++ 程序剖析之主要类解析
    • Binder 服务注册进程情形剖析之 C++ 篇
  • HAL 与硬件服务

    • Kernel 下载与编译
    • Linux 驱动开发入门

本文基于 AOSP Android10_r41 源码环境。

假如提前阅读了以下文章,本文阅读起来会愈加顺利:

  • Ubuntu 运用快速入门
  • AOSP 极速上手
  • 体系开发东西
  • Make 构建东西入门
  • 增加 Product
  • AOSP 中增加 C/C++、Java 可履行程序

1.增加 C/C++ 程序库

1.1 源码办法增加

device/Jelly/Rice14/ 目录下创立以下的目录和文件

libmymath
├── Android.bp
├── my_math.cpp
└── my_math.h

libmymath 是一个动态库。其 Android.bp 内容如下:

cc_library_shared {
    name: "libmymath",
    srcs: ["my_math.cpp"],
    export_include_dirs: ["."],
    product_specific: true,
}

my_math.h 内容如下:

#ifndef __MY_MATH_H__
#define __MY_MATH_H__
int my_add(int a, int b);
int my_sub(int a, int b);
#endif

my_math.cpp 内容如下:

#include "my_math.h"
int my_add(int a, int b)
{
	return a + b;
}
int my_sub(int a, int b)
{
	return a - b;
}

接着修正咱们之前增加的 hello 项目:

修正 hello.cpp

#include <cstdio>
#include "my_math.h" //增加头文件
int main()
{
    printf("Hello Android %d \n", my_add(1,2)); //增加函数调用
    return 0;
}

修正 Android.bp:

cc_binary {
    name: "hello",       
    srcs: ["hello.cpp"], 
    cflags: ["-Werror"], 
    product_specific: true,        
    shared_libs: ["libmymath"]    //增加动态库依靠
}

接下来编译体系:

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

编译完结启动虚拟机后,就能够通过 adb shell 运转咱们的 hello 程序了

emulator
adb shell hello

履行成果如下图所示:

写给应用开发的 Android Framework 教程——玩转 AOSP 篇之添加 C/C++、Java 库

1.2 so 包办法增加

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

libmymathprebuild
├── Android.bp
├── include
│   └── my_math.h
└── lib
    ├── x86
    │   └── libmymath.so
    └── x86_64
        └── libmymath.so
  • 其中 libmymath.so 是上一节中的编译产品,x86/libmymath.so 复制自 out/target/product/Rice14/system/product/lib/libmymath.so
  • x86_64/libmymath.so 复制自 out/target/product/Rice14/system/product/lib64/libmymath.so
  • my_math.h 是上一节中 libmymath 模块中复制过来的头文件

Android.bp 的内容如下:

cc_prebuilt_library_shared {
    name: "libmymathprebuild",
     arch: {
        x86: {
            srcs: ["lib/x86/libmymath.so"],
        },
        x86_64: {
            srcs: ["lib/x86_64/libmymath.so"],
        }
    },
    export_include_dirs: ["include"],
    product_specific: true,
}

为了防止抵触,咱们把上一节增加的 libmymath 移出体系源码目录或者删去。

接下来,编译整个体系,敞开虚拟机

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

接下来履行 hello 程序

adb shell hello

履行成果如下图所示:

写给应用开发的 Android Framework 教程——玩转 AOSP 篇之添加 C/C++、Java 库

2. 增加 Java 库

2.1 源码办法增加

device/Jelly/Rice14/ 目录下创立以下的目录和文件:

libmymathjava
├── Android.bp
└── com
    └── yuandaima
        └── mymath
            └── MyMath.java

libmymathjava 是一个 java 库。其 Android.bp 内容如下:

java_library {
    name: "libmymathjava",
    installable: false,
    product_specific: true,
    srcs: ["**/*.java"],
    sdk_version: "current"
}

假如不指定 installable: true, 则编译出来的 jar 包里边是 .class 文件。这种包是无法安装到体系上的,只能给其他 java 模块作为 static_libs 依靠。最终生成的 jar 包不会被直接存放到 Android 的文件体系中,而是打包进依靠于当时模块的其他模块中。

MyMath.java 内容如下:

package com.yuandaima.mymath;
public class MyMath
{
    public MyMath() {
    }
	public int add(int a, int b)
	{
		return (a+b);
	}
}

接着咱们把 helllojavajar 删去,将之前写好的 hellojava 模块移动到 device/Jelly/Rice14 目录下,并做以下修正:

修正 helljava/Android.bp:

device/Jelly/Rice14/Rice14.mk 中增加:

PRODUCT_PACKAGES += hellojava

接下来编译体系:

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

编译完结启动虚拟机后:

# 进入模拟器shell
adb shell
# 装备 classpath
export CLASSPATH=/product/framework/hellojava.jar
app_process /product/framework/ com.ahaoyuandaima.main.HelloJava 

履行成果如下图所示:

写给应用开发的 Android Framework 教程——玩转 AOSP 篇之添加 C/C++、Java 库

2.2 Jar 包办法增加

在体系源码目录下履行:

source build/envsetup.sh
lunch Rice14-eng

接下来编译取得 jar 包:

cd device/Jelly/Rice14/libmymathjava
mm
#编译完结后,会打印出编译产品途径 out/target/product/Rice14/obj/JAVA_LIBRARIES/libmymathjava_intermediates/javalib.jar

为防止抵触咱们把 device/Jelly/Rice14/libmymathjava 移动到源码以外的目录或者删去

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

libmymathjavajar
├── Android.bp
└── libmymathjava.jar

其中 libmymathjava.jar 是复制自编译产品 out/target/product/Rice14/obj/JAVA_LIBRARIES/libmymathjava_intermediates/javalib.jar,并改名为 libmymathjava.jar

Android.bp 的内容如下:

java_import {
    name: "libmymathjavajar",
    installable: false,
    jars: ["libmymathjava.jar"],
    product_specific: true,   
}

接着修正 hellojava 模块的依靠:

java_library {
    name: "hellojava",
    installable: true,
    product_specific: true,
    srcs: ["**/*.java"],
    sdk_version: "current",
    static_libs: ["libmymathjavajar"]  //修正这儿
}

编译体系,并启动模拟器:

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

验证 libmymathjavajar 模块是否被正确编译到 hellojava 模块中。

# 进入模拟器shell
adb shell
# 装备 classpath
export CLASSPATH=/product/framework/hellojava.jar
app_process /product/framework/ com.ahaoyuandaima.main.HelloJava 

履行成果如下:

写给应用开发的 Android Framework 教程——玩转 AOSP 篇之添加 C/C++、Java 库

参考资料

  • How to include prebuilt library in Android.bp file?
  • Android体系开发入门-5.增加预编译模块
  • Android.bp 文件中引进aar、jar、so库正确编译办法(值得保藏)
  • 在AOSP中增加jar包和aar包依靠
  • Android体系开发入门-4.增加自定义模块
  • Android 10 根文件体系和编译体系(十九):Android.bp各种模块编译规矩
  • Soong Modules Reference
  • Android.bp编译提示ninja: error: unknown target ‘MODULES-IN-xxx‘终极攻略
  • Failing builds for Lineage-19.0 due to artifact path requirement
  • 自定义 SELinux
  • Android体系build阶段签名机制
  • android体系源码中增加app源码(源码布置移植)

关于

假如你对 Android Framework 感兴趣,能够继续重视:

  • 平台个人技术博客
  • 我的个人公众号

写给应用开发的 Android Framework 教程——玩转 AOSP 篇之添加 C/C++、Java 库

  • 我的个人微信(能够加我微信进 Android Framework 交流群)

写给应用开发的 Android Framework 教程——玩转 AOSP 篇之添加 C/C++、Java 库