I'm trying to use the Runtime Resource Overlay (RRO) mechanism to overlay an xml resource, which is using custom attributes and custom namespace. When building the overlay APK the aapt2 (link) throws an attribute not found error.
How do I make known the custom attribute from the main application to the overlay?
Is it even possible to use custom attributes in an overlay?
Details:
The overlay contains of two files:
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>
and the xml file 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" -->
The main application defines the attribute text in res/values/attrs.xml:
...
<declare-styleable name="MyConfig">
<attr name="text" format="string" />
</declare-styleable>
Furthermore it defines the overlayable tag in res/values/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>
To build the overlay I do this:
aapt2 compile -v --dir app/src/main/res/ -o SimpleAppOverlay.flata
and
aapt2 link -v --no-resource-removal
-I ~/Library/Android/sdk/platforms/android-29/android.jar
--manifest app/src/main/AndroidManifest.xml
-o sao.apk SimpleAppOverlay.flata
Which leads to the following output:
note: including /Users/bernd/Library/Android/sdk/platforms/android-29/android.jar
aapt2 W 09-01 14:33:06 20083 694697 ApkAssets.cpp:138] resources.arsc in APK '/Users/bernd/Library/Android/sdk/platforms/android-29/android.jar' is compressed
note: linking package 'de.test.simpleappoverlay' using package ID 7f note: merging archive SimpleAppOverlay.flata
note: merging 'xml/my_config' from compiled file app/src/main/res/xml/my_config.xml
note: enabling pre-O feature split ID rewriting AndroidManifest.xml:
note: writing to archive (keep_raw_values=false)
note: writing AndroidManifest.xml to archive note: linking 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 (aka de.test.simpleappoverlay:text) not found
error: failed linking file resources.
I had a similar problem to this where I was trying to overlay an app with custom attributes in Android 10 and have a solution. There are two changes that are needed:
Part 1
It looks like your app name is de.test.simpleapp so your my_config.xml file should look like:
The important piece is specifying the 'prv/res/app.packagename' so it uses the namespace of the base app for the private attributes. If you used 'apk/res-auto' that would not work as it resolves to the name of your app (which in this case is the overlay app de.test.simpleappoverlay) which does not contain the definition of the private attributes.
Part 2
Since you now have a dependency on the main app when linking, you have to include it in the link command with a
-I simpleapp.apk
(or whatever the APK name is of the base app). Right now you are just including android.jar in the aapt2 link step which only contains the 'android' namespace and attributes. Therefore, you now need to add your base app in the include step so it can link properly against its namespace and attributes.Like some of the other answers said though, this problem goes away in Android 11, but if you're stuck on Android 10 like I am hopefully this helps.