工作中,你一定会遇到需要往ROM中添加jar包的需求,今天介绍一下如何往ROM中添加一个新的jar包(以Android4.4和Android6.0为例)。

如果你是一个APP开发者,那么在apk中添加引用第三方的jar包对你来说一定是家常便饭;但是在ROM的开发中,如果需要添加一个公用的jar包,最好的办法就是把jar包放到rom中。

1. Android.mk

在AOSP(Android Open Source Project)中添加jar包,需要编写Android.mk

LOCAL_PATH := $(call my-dir)

# Build the Java library.
include $(CLEAR_VARS)

LOCAL_MODULE := com.abc.android
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
    $(call all-java-files-under, java)
LOCAL_JAVA_LIBRARIES += com.xyz.android

include $(BUILD_JAVA_LIBRARY)
  • 这段Makefile因为使用了include $(BUILD_JAVA_LIBRARY), 所以最后编译出来的就是jar包。
  • LOCAL_MODULE指定了编译出来的jar包的名字
  • LOCAL_JAVA_LIBRARIES指定了编译这个jar包时,需要引用和依赖的别的jar包

在编写完jar包的源代码和Android.mk之后,还需要保证这个Android.mk可以被编译到。可以查看这篇文章:Android build system[一]

2. 打包到system.img

在第一步之后,jar包可以被正常编译出来,但是你会发现,在你生成的system.img中,一定找不到com.abc.android.jar这个文件。原因就是Android编译系统并没有将这里编译出来的jar文件打包到
system.img里。我们需要通过PRODUCT_PACKAGES指定(一般是在device/对应的product目录下,或者直接在build目录下添加)。

PRODUCT_PACKAGES += com.abc.android

这样,编译之后,就能够在system.img里找到com.abc.android.jar文件了。

3. dex优化jar包

前两步之后,jar包被成功打包到system.img中,但是这时,那些使用了com.abc.android.jar的apk是无法正常在手机上使用的。因为虽然jar包已经在system分区了,但是它并没有被预先加载到虚拟机中,当使用这个jar
包的apk启动的时候,找不到jar包里编译出来的二进制文件。通过修改PRODUCT_BOOT_JARS可以解决(同样是在device/对应的product目录下,或者直接在build目录下添加)。

PRODUCT_BOOT_JARS = com.abc.android

PRODUCT_BOOT_JARS变量里的值在编译时,会先被加上’system/framework/’前缀放到PRODUCT_BOOTCLASSPATH变量中去,然后再把PRODUCT_BOOTCLASSPATH的值放到BOOTCLASSPATH中去。BOOTCLASSPATH又在init.rc里被设置成系统环境变量。

export BOOTCLASSPATH /system/framework/core.jar:/system/framework/conscrypt.jar: ... :/system/framework/com.abc.androidd.jar

在Android系统开机时Zygote启动dalvik时,会读BOOTCLASSPATH这个环境变量,然后把这里所有的jar包进行dexopt操作,变成虚拟机可以直接运行的格式。

到这里,就可以正常运行使用这个新加的jar包的app了.