我试图使用运行时资源覆盖(,RRO)机制覆盖xml资源,该资源使用自定义属性和自定义命名空间。在构建覆盖APK时,aapt2 (链接)抛出一个属性未找到错误。
如何将自定义属性从主应用程序告知覆盖层?
甚至可以在覆盖层中使用自定义属性吗?
详细信息:
覆盖包含两个文件:
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.test.simpleappoverlay">
<overlay
android:targetPackage="de.test.simpleapp"
android:targetName="Test"/>
</manifest>
以及xml文件res/xml/my_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<MyConfig xmlns:app="http://schemas.android.com/apk/res/de.test.simpleapp"
app:text="hello">
</MyConfig>
<!-- I also tried: xmlns:app="http://schemas.android.com/apk/res-auto" -->
主应用程序在res/value/atts.xml中定义了属性文本:
...
<declare-styleable name="MyConfig">
<attr name="text" format="string" />
</declare-styleable>
此外,它在res/value/overlayable.xml中定义了可覆盖标记:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<overlayable name="Test">
<policy type="public">
<item type="xml" name="my_config"/>
</policy>
</overlayable>
</resources>
为了构建覆盖,我这样做:
aapt2编译-v --dir app/src/main/res/ -o SimpleAppOverlay.flata
和
aapt2 link -v --无资源删除
-I ~/Library/Android/sdk/platforms/android-29/android.jar
-清单app/src/main/AndroidManifest.xml
-o sao.apk SimpleAppOverlay.flata
这将导致以下输出:
注意:包括/Users/bernd/Library/Android/sdk/platforms/android-29/android.jar
'/Users/bernd/Library/Android/sdk/platforms/android-29/android.jar‘中的aapt2 W 09-01 14:33:06 20083 694697 ApkAssets.cpp:138] resources.arsc被压缩
注意:使用包ID 7f链接包'de.test.simpleappoverlay‘注意:合并归档SimpleAppOverlay.flata
注意:从编译后的文件app/src/main/res/xml/my_config.xml合并'xml/my_config‘
注意:启用预O特性拆分ID重写AndroidManifest.xml:
注:写到存档(keep_raw_values=false)
注意:编写AndroidManifest.xml存档说明:链接app/src/main/res/xml/my_config.xml (de.test.simpleappoverlay:xml/my_config)
app/src/main/res/xml/my_config.xml:2: error: attribute text (又名de.test.simpleappoverlay:text)未找到
错误:链接文件资源失败。
发布于 2021-06-10 09:38:16
我遇到了一个类似的问题,当时我试图在Android 10中覆盖一个带有自定义属性的应用程序,并有一个解决方案。需要进行两项更改:
第1部分
看起来您的应用程序名是de.test.simpleapp,所以您的my_config.xml文件应该如下所示:
<?xml version="1.0" encoding="utf-8"?>
<MyConfig xmlns:app="http://schemas.android.com/apk/prv/res/de.test.simpleapp"
app:text="hello">
</MyConfig>
重要的部分是指定'prv/res/app.packagename‘,因此它将基本应用程序的命名空间用于私有属性。如果您使用的是‘apk/res’,这将无法工作,因为它解析为应用程序的名称(在本例中是覆盖应用程序de.test.simpleappoverlay),它不包含私有属性的定义。
第2部分
因为现在链接时依赖于主应用程序,所以必须将其包含在带有-I simpleapp.apk
的链接命令中(或者使用基本应用程序的任何APK名称)。现在,您只是将android.jar包含在aapt2链接步骤中,该步骤只包含'android‘命名空间和属性。因此,您现在需要在include步骤中添加您的基本应用程序,这样它就可以正确地链接到它的命名空间和属性。
就像其他一些答案说的那样,这个问题在Android 11中解决了,但是如果你像我一样被困在Android 10上,希望这会有所帮助。
发布于 2021-02-03 02:59:46
我认为在RRO的当前实现中不支持包括新的in (至少在Android中是这样)。对于您的错误,aapt使用android.jar为您的覆盖生成apk。因为它找不到您的新属性,所以会抛出一个错误。为此,我相信您需要使用经过修改的android.jar,包括您的属性。其中一种方法是修改AOSP中的Android,并创建您自己的版本,然后将其用于aapt命令。
发布于 2021-03-27 08:49:16
不久前,我将AOSP环境从Android 10改为11,Google对覆盖机制做了不少修改。令我惊讶的是,这些更改修复了我在尝试“覆盖”自定义属性时遇到的问题。
在Android 10环境中,我在调试时观察到,当尝试读取上述属性时,Android解析器返回"null“。使用idmap,我能够确认属性是否存在于覆盖层和目标应用程序中,并且它们被正确地映射。
此外,所有链接错误都消失了。
https://stackoverflow.com/questions/63688541
复制相似问题