Chromium Android工程迁移编译过程
本文从Chromium编译的中间产物入手深入分析、学习Chromium Android版本的工程化定制流程。初始工作依赖于Chromium的ninja、GYP构建系统,在构建完成后基于编译中间产物,迁入Android Studio作为新的构建工程,测试编译发布的过程。
注:这种编译过程除了资源文件外其他编译中间产物,都不可修改,不具备大规模定制化的可能性,仅作为熟悉编译过程和代码结构的学习、测试使用。
前提
Chromium代码结构、Android开发、Android Studio使用
编译Chromium
编译步骤可以参考Chromium团队的文章,可以选择编译目标为chrome_public_apk、content_shell_apk,本文以chrome_public_apk为例。
编译结果APK
在以chrome_public_apk为编译目标后,在经历一段时间后编译完成,在out/***文件夹内就包含了所有的编译结果和编译中间产物,其中apk在apks文件夹内,可以拉取安装一下,除了包名外其他功能与Chrome基本一致,本文的迁移目标就是在Android Studio工程下同样可以编译出这个APK,再探讨后续的源码迁移和定制工作。
工作目录
在out/***文件夹下,我们主要涉及到的文件分为三类:so、jar、resource,各自又来自不同的Chromium模块。
apks---编译目标文件目录
gen---编译过程中间产物,基本不涉及
lib.java---jar文件的主要来源,将不同模块的java文件编译后汇集在这个目录
locale---国际化的资源文件
resource-zips---资源文件的主要来源,也是Android Studio module化的主要依据
lib.unstripped---so文件目录
建立Android Studio工程
由于Chromium原有模块是基于命名空间来管理的,而且Android的R资源文件定义方式与此关联,所以需要通过Android Application、Library module的方式进行区分,同时还需要将Android Support这一类第三方库通过Gradle依赖的方式进行关联,而不是JAR+资源文件的方式。
所以基于Chromium的模块划分方式分为如下几个子module:
app---org.chromium.chrome,主App Application
ui---org.chromium.ui,Android Library
base---org.chromium.base,Android Library
components---com.chromium.components,Android Library
content---org.chromium.content,Android Library
media---org.chromium.media,Android Library
autofill---org.chromium.components.autofill,Android Library
web_contents_delegate_android---org.chromium.components.web_contents_delegate_android,Android Library
third_party---com.chromium.third_party,Android Library
tools---org.chromium.tools,Android Library
url---org.chromium.url,Android Library
builder---org.chromium.build,Android Library
net---org.chromium.net,Android Library
mojo---org.chromium.mojo,Android Library
device---org.chromium.device,Android Library
gpu---org.chromium.gpu,Android Library
printing---org.chromium.printing,Android Library
services---org.chromium.services,Android Library
skia---org.chromium.skia,Android Library
迁移编译后so
lib.unstripped目录下的所有so文件,迁入主工程的jniLibs文件中,并在CMake文件中配置引入,切记。
add_library(xxx SHARED IMPORTED)set_target_properties(xxx PROPERTIES IMPORTED_LOCATION src/main/jniLibs/${ANDROID_ABI}/libxxx.so)
迁移编译后Jar
lib.java目录下按照已经建立好的Android Library工程分别放入libs目录下,注意仅放入非interface.jar的文件,否则可能导致duplicate class问题,同时注意JAR文件重名问题,建议以多多级目录重命名的方式导入。
迁移编译后Resource
gen/chrome/android/chrome_public_apk目录下的AndroidManifest.xml 拷贝到主工程中
resource_zips目录下也同样按照Android Library工程分别解压放入res目录下,尤其注意覆盖问题,因为同一模块下可能有同名的资源文件。android_deps、gvr目录下的资源文件不引入,后续将通过Gradle依赖方式引入。
除此之外还需要将额外的资源文件引入主工程assets目录中,并且禁用压缩。文件如下:chrome_100_percent.pak
icudtl.dat
resources.pak
snapshot_blob.bin
locales目录(包含目录这一级)
修正工程参数+Gradle
上述步骤做完以后工程不能如期运行,还需要调整几个地方,因为有些java文件是在编译过程中生成的:
gen/chrome/android/chrome_public_apk__build_config_java下的buildConfig.java
此文件主要定义启动参数等信息,这个文件主要参考信息,由于Gradle编译的过程中最终会覆盖这个文件,所以里面的所有参数需要通过Gradle配置进行定义。
gen/chrome/android/chrome_public_apk__native_libraries_java下的NativeLibraries.java
此文件主要定义了需要引入哪些so文件、版本号等信息。
运行编译
这一系列的步骤,可以通过一步步的运行报错进行修正,最后得到正确运行的编译包。最后还是那句话,这只是探索定制化过程的一小小步,Chromium项目庞大,需要长久的深入。
如果只是想体验一下迁移后的结果工程,文末附Github工程。