欢迎光临
专注android技术,聚焦行业精粹,我们一直在努力

android-重打包-改包名

1、问题背景:

拿到一个已经编译好的APK,我们如何修改它的包名,并重新打包。

2、问题分析:

我们这里指的修改包名是修改AndroidManifest文件中manifest标签里面的packageName,那么我们修改了manifest标签里面的packageName,其余代码中通过 xxx.xxx.xxx.R.drawable.xxx 这种方式引用到该包名的代码也需要一起修改。

3、实现方法 :

3.1、方式一:反编译并修改AndroidManifest.xml里面的package属性

使用到apktool工具,apktool可以将apk包反编译,得到我们想要修改的manifest文件,打开编辑包名,并使用apktool重新打包最终得到改完包名的apk。

具体步骤如下:

1)我们通过jadx工具反编译需要修改包名的apk文件,看到Test2.java代码中已经用包名引用的R类。此时我们的目标也要修改此处引用的包名。

2)通过apktool反编译apk包

使用如下的命令:

apktool命令的参数如下:

我们用到了-s,不反编译dex文件,因为我们只修改manifest文件。

执行完上面的命令后得到如下的目录结构:

3) 编辑AndroidManifest文件,修改packageName为“test.conio.com.change”:

4)通过apktool重新打包

使用命令如下:

再通过jadx工具反编译查看包名是否都修改OK:

纠正一下:图中的changenow应该是change,截图时没有与前面对应

5)给包重签名打包运行验证OK

3.2、方式二:通过aapt的–rename-manifest-package参数修改

另一种方式:aapt 有一个 –rename-manifest-package 参数会修改最终apk里面AndroidManifest.xml二进制文件里面的packcage属性

apk 包里有3种包名:

  • AndroidManifest.xml 的 package 属性:该包名用于唯一区分一个应用程序的。也就是应用的唯一标识。
  • applicationId: 网上有很多分析它与manifest的package的区别。我总结一句话是,applicationId最终在输出包时会写到AndroidManifest.xml的package属性,它是应用的唯一标识。但修改package属性值之前会将manifest里面四大组建的相对路径(即.开头的类名用旧的package属性值补全为完整路径),如下图所示(gradle文件里面的appcliationId在原包名基础上多了.applicationId后缀,此时下面的MainActivity由“.MainActivity”变为“com.example.ali.testandroid.MainActivity”,即自动用旧包名补全了):
  • Resources.arsc里面的包名:我们在资源文件里面自定义attribute的时候会用到这个包名,它的值通常与上面AndroidManifest.xml里面的package属性值时一样的(如果设置了applicationId,那么Manifest里面的package属性值是这个新的applicationId,同时resources.arsc文件里面的包名也是这个applicationId的值)。除非我们通过aapt的 –rename-manifeset-package修改了manifest的值,这样它们就不一样了。

修改applicationId后manifest里面package和MainActivity的变化

修改applicationId后resources.arsc文件的包名变化

通常情况下Resources.arsc的包名会读取AndroidManifest.xml的package属性值。但程序也可以在aapt打包时通过–rename-manifeset-package修改最终输出apk的二进制AndroidManifest里面的package属性,那么此时Resources.arsc的里面的包名信息就和AndroidManifest里面的包名不一致了。

aapt的帮助文档是这样描述–rename-manifest-package参数的:

–rename-manifest-package

Rewrite the manifest so that its package name is the package name given here.  Relative class names (for example .Foo) will be changed to absolute names with the old package so that the code does not need to change.

aapt的这种方式只会修改manifest里面的package属性,但不会修改resource.arsc文件的包名,这会导致在一些场景出错。apktool作者也遇到同样的问题:

原文地址:链接

对于–rename-manifest-package引起的问题,apktool的解决方案如上面截图描述,总体的意思如下:

–rename-manifest-package 会修改apk包里的二进制manifest文件package属性,但不会修改resources.arsc里面的包名。apktool在反编译时会先判断如果AndroidManifest.xml里面的package属性值和resources.arsc里面的包名信息不一致时,就认为apk包用了–rename-manifest-package参数修改了包名导致的。于是apktool会先将AndroidManifest.xmlpackage属性值保存在apktool.yml文件的renameManifestPackage属性里面,然后将AndroidManifest里面的package属性值改为为resources.arsc里面的包名。这样在构建包时不会出错。

同时构建过程中也会通过aapt的–rename-manifest-package参数将之前的package属性值(保存在apktool.yml文件里面)再还原回来,保持apktool重新构建回来后和原来的包的内容不变。

4、结论

我们通过apktool反编译包后,手动修改AndroidManifest.xml的包名,aapt最终可以保证和resources.arsc同步一致。如果此前该包用–rename-manifest-package参数修改了包名,那么apktool也会缓存该值在apktool.ymlrenameManifestPackage属性,并在最终合包是还原回来。

记住如果想要修改apk的包名,官方建议修改AndroidManifest.xml文件的package属性,而不是apktool.ymlrenameManifestPackage属性,其实通过这篇文章之前的论述我们能知道,这个renameManifestPackage属性值是用来针对–rename-manifest-package这个参数来做的特殊处理,而最终输出apk的AndroidManifest里面的package属性才是真正的应用唯一标识

赞(2) 打赏
未经允许不得转载:花花鞋 » android-重打包-改包名
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

国内精品Android技术社区

联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏