导语 : 在Windows下定制自己的aapt! |
---|
Codeblocks
下载地址:<
mingw64
下载地址:<https://jaist.dl.sourceforge.net/project/tdm-gcc/TDM- GCC%20Installer/>
aapt
源码地址(为了避免麻烦,特地弄好了aapt
的Codeblocks
项目,直接从我的github
上clone
下来就能在Codeblocks
中用):https://github.com/ClaymanTwinkle/aapt
软件安装好了就要先配置下
Codeblocks
配置Compiler
步骤一:
选择进入工具栏 Settings
» Compiler
,如下图所示;
步骤二:
(1)选择Global compiler settings
;
(2)在Selected compiler
中选择GNU GCC Compiler
,然后下方点击Copy
按钮,就会出现Copy of GNU GCC Compiler
;
(3)在下方Toolchain executables
配置mingw64
,相关配置如下图所示;
(4)最后选择OK
即可;
配置好编译环境后,就可以打开项目了;进入aapt/aapt-v24
中打开aapt-v24.workspace
;
工程目录结构如下图所示;
Compiler
步骤一:右键一个工程,在右键菜单中选择Build Options
;
步骤二:第一次配置的时候,会出现一个弹窗,如下图;选择刚刚自己创建的Copy of GNU GCC Compiler
,点击确定;
步骤三:注意,如果此时,出现以下对话框,请选择否
;
对每个工程重复以上步骤;
aapt
源码没错,如果上面的步骤都弄成功了,现在就可以改aapt源码了,是的,在Windows上改aapt源码,想想就激动! 普及一下一个小知识,在
R.Java
中可以看到系统资源的id都是以0x01
开头的,而自己的资源id都是以0x7f
开头的;这也就是说0x01
到0x7f
之间的的值我们都可以拿来用。 废话不多说,赶紧动手!
0x7f
为0x66
(1)在CodeBlocks
中打开aapt-v24
,找到我们要找的入口类main.cpp
;同时也找到了入口方法main
;
(2)找到这个main.cpp
有什么用,怎么修改0x7f
呢?
我们可以这样,按快捷键
Ctrl+F
(真的很好用!),在aapt-v24
中搜索0x7f
,如下图所示;
搜索结果如下,这样我们就找到赋值
0x7f
的地方了;
在
ResourceTable.cpp
这个类中;
(3)既然找到了位置,那赶紧改下这个值试试(直接改硬编码不太优雅,后面介绍一种优雅的方式),修改结果如下图所示;
接着,打包出自己的
aapt
吧!
(4)右键aapt-v24
,在右键菜单中选择build
或者rebuild
,编译成功,打包出aapt.exe
。
从
aapt\aapt-v24\bin\Debug
目录下可以看到打包好的aapt-24.exe
。
(5)打包好了,是骡子是马牵出来溜溜吧。
随便找个
Android
工程,然后在cmd
中敲出类似这样一段命令行生成R.java
:aapt-v24.exe p -f -m -I C:\Android\sdk\platforms\android-25\android.jar -J C:\Users\andyqtchen\Desktop\plurals -M C:\Android\workspace\AndroidQQ_Lite_proj/QQLite//AndroidManifest.xml -S C:\Android\workspace\AndroidQQ_Lite_proj/QQLite/res
结果……出乎意料啊,居然错了,是啊,哪有那么容易,想得美;但是,这些
log
好像是aapt
自己内部打印出来吧?让我们看看这些log
是从哪里打印出来的!
(6)神一样的快捷键Ctrl+F
,搜~,结果如下图所示;
原来是在
androidfw
工程下的ResourceTypes.cpp
搞的鬼! 先看看ResourceTypes.cpp
耍的是什么把戏!
原来是这么回事,
aapt
除了会在aapt-v24
中赋值,在androidfw
中后面还会做一个判断拦截;
那么我在这里再加一个或者packageId==0x66
就ok了(又一不文明操作,请勿模仿)!
改完重新rebuild androidfw
,然后rebuild aapt-24
打包出aapt.exe
;
重新生成一次R.java
,接下来就是见证奇迹的时刻!
aapt
好了,上面的
2.1
只是小打小闹的一个实验而已,接下来要定制下随意修改资源ID
前缀(packageId
)的aapt
;
我在
androidfw
中定义一个单例,用来记录0x7f
(默认值)或者其他自定义packageId
的值;
// BlinkPackageId.h文件
#ifndef __BlinkPackageId_h
#define __BlinkPackageId_h
#include
#include
#include
#include
#include
#include
#include
using namespace std;
class BlinkPackageId
{
ssize_t mPackageId;
public:
static BlinkPackageId* getInstance()
{
static BlinkPackageId instance;
return &instance;
}
ssize_t getPackageId();
void setPackageId(ssize_t packageId);
void setPackageId(const char* packageId);
protected:
struct Object_Creator
{
Object_Creator()
{
BlinkPackageId::getInstance();
}
};
static Object_Creator _object_creator;
BlinkPackageId() {
mPackageId=0x7f;
}
~BlinkPackageId() {
}
};
#endif
// BlinkPackageId.cpp文件
#include
#include
#include
#include
using namespace std;
// char2int
static uint32_t apkgetHex(char c, bool* outError){
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'a' && c <= 'f') {
return c - 'a' + 0xa;
} else if (c >= 'A' && c <= 'F') {
return c - 'A' + 0xa;
}
*outError = true;
return 0;
}
// string2int
static ssize_t apkStringToInt(const android::String8& s){
size_t i = 0;
ssize_t val = 0;
size_t len=s.length();
if (s[i] < '0' || s[i] > '9') {
return -1;
}
// Decimal or hex?
if (s[i] == '0' && s[i+1] == 'x') {
i += 2;
bool error = false;
while (i < len && !error) {
val = (val*16) + apkgetHex(s[i], &error);
i++;
}
if (error) {
return -1;
}
} else {
while (i < len) {
if (s[i] < '0' || s[i] > '9') {
return false;
}
val = (val*10) + s[i]-'0';
i++;
}
}
if (i == len) {
return val;
}
return -1;
}
BlinkPackageId::Object_Creator BlinkPackageId::_object_creator;
ssize_t BlinkPackageId::getPackageId(){
return mPackageId;
}
void BlinkPackageId::setPackageId(ssize_t packageId){
mPackageId=packageId;
}
void BlinkPackageId::setPackageId(const char* packageId){
android::String8 str = android::String8(packageId);
mPackageId=apkStringToInt(str);
}
aapt
命令行定个需求,要加个
--blink-package-id
命令参数,后面带packageId
;
锁定到aapt-v24
工程下main.cpp
源代码:
在ResourceTable.cpp
,将0x7f
改成BlinkPackageId::getInstance()->getPackageId()
然后到androidfw
工程下,把BlinkPackageId::getInstance()->getPackageId()
放到if
中:
ok!大功告成!
看看效果!!!
aapt-v24.exe p -f -m -I C:\Android\sdk\platforms\android-25\android.jar -J C:\Users\andyqtchen\Desktop\plurals -M C:\Android\workspace\AndroidQQ_Lite_proj/QQLite//AndroidManifest.xml -S C:\Android\workspace\AndroidQQ_Lite_proj/QQLite/res --blink-package-id 0x55
如何实现携程动态加载插件中对aapt的改造 Android中如何修改编译的资源ID值(默认值是0x7F…可以随意改成0x02~0x7E)