您的位置:首页 > 移动开发 > Android开发

Android插件化开发之OpenAtlas资源打包工具补丁aapt的编译

2015-08-19 12:42 302 查看
我们先来看看Android Studio自动生成的R文件里的内容,你会发现,R文件里有很多内部类,而内部类里有很多int类型的值,他们都是以0x7f开头。



我们在编译一个Android应用程序的资源的时候,至少会涉及到两个包,其中一个是被引用的系统资源包,另外一个就是当前正在编译的应用程序资源包。每一个包都可以定义自己的资源,同时它也可以引用其它包的资源。那么,一个包是通过什么方式来引用其它包的资源的呢?这就是我们熟悉的资源ID了。资源ID是一个4字节的无符号整数,其中,最高字节表示Package ID次高字节表示Type ID,最低两字节表示Entry ID

Package ID相当于是一个命名空间,限定资源的来源。Android系统当前定义了两个资源命令空间,其中一个系统资源命令空间,它的Package ID等于0x01,另外一个是应用程序资源命令空间,它的Package ID等于0x7f。所有位于[0x01, 0x7f]之间的Package ID都是合法的,而在这个范围之外的都是非法的Package ID。前面提到的系统资源包package-export.apk的Package ID就等于0x01,而我们在应用程序中定义的资源的Package ID的值都等于0x7f,这一点可以通过生成的R.java文件来验证。

Type ID是指资源的类型ID。资源的类型有animator、anim、color、drawable、layout、menu、raw、string和xml等等若干种,每一种都会被赋予一个ID。

Entry ID是指每一个资源在其所属的资源类型中所出现的次序。注意,不同类型的资源的Entry ID有可能是相同的,但是由于它们的类型不同,我们仍然可以通过其资源ID来区别开来。

更多详情可以先了解一下下面的两篇文章的内容。

- Android资源管理框架(Asset Manager)简要介绍和学习计划

- Android应用程序资源的编译和打包过程分析

所有Atlas的插件,都需要在build.gradle文件中指定资源分区,也就是versionName后加上[0x1, 0x7f]之间的值,使用补丁aapt进行打包。

我们可以通过补丁aapt打印出package id看看,会发现package id就是我们指定的0x21



Atlas的Android资源可以大致分为两部分,系统层资源和应用层资源

系统层资源分为三部分主要(5.0一下版本分为两部分)

系统框架层 ,Android的核心框架层资源id为 0x01

共享资源层 ,这部分的资源id为0x00,跟开发者关系不大,我们不会直接使用这部分

WebView层,资源id为0x02.(这个在Android 5.0开始有的)(GoogleWebView.apk)

应用层分为两部分,宿主层和组件层

组件层资源相互独立,互不冲突,(id分布从0x10 到 0x7e)

宿主层的资源还是0x7f,保持默认值。

其中,宿主层包含共享资源(类似于系统的共享资源),组件层可能依赖于宿主层的共享资源(计划1.0支持)

总结为以下这幅图



要实现资源的分区,就必须使用打过补丁的aapt进行资源的打包。下面我们对补丁aapt进行编译。

编译环境是Ubuntu 14.04,参考http://source.android.com/source/initializing.html进行环境配置。

$ sudo apt-get update
$ sudo apt-get install openjdk-7-jdk
$ sudo apt-get install bison g++-multilib git gperf libxml2-utils make python-networkx zlib1g-dev:i386 zip


环境变量的临时增加

$ mkdir ~/bin
$ PATH=~/bin:$PATH


下载repo工具,这一步需要***,可以使用hosts,hosts见http://laod.cn/hosts/2015-google-hosts.html

$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo


git配置

$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"


源码下载,使用清华大学的镜像

$ mkdir ~/Android
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest
$ repo sync


接下来就是等吧,等的时间看你的网速了。100M的速度,大概也要好几个小时吧,差不多一天,支持断点续传

配置环境

$ cd Android
$ . build/envsetup.sh


完成后进入以下目录

$ cd Android/frameworks/base


将openatlas中的base.patch拷到该目录下。应用该patch,应用前最好切换到对应的分支(大概是android5.1.1的分支,具体哪个分支不清楚)

$ patch -p1 < base.patch


没有出错的话就应用成功了。

编译aapt,如果要编译windows的版本,注意加上USE_MINGW=1

$ USE_MINGW=1 make aapt


如果只是linux版的,就直接

$ make aapt


如果没有出错就编译成功了,对应的文件在

Android/out/host/windows-x86/bin


或者

Android/out/host/linux-x86/bin


替换原来的aapt即可。但是后来发现编译完成的aapt比作者提供的aapt大了好多。。。。原因未知。。

如果在编译过程中提示

android comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Werror,-Wsign-compare]


找到对应文件中的代码,进行强制转换为int后再比较(不知是否有影响,源码没仔细看),所以最好切换到对应的分支上再应用patch

替换原aapt,进行测试,如果插件运行正常,差不多就成功了。下图是打印的结果,发现package已经被修改了,运行结果图就不贴了

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: