具有自定义属性的Android运行时资源叠加层

问题描述

我正在尝试使用运行时资源覆盖(RRO)机制来覆盖xml资源,该资源正在使用自定义属性和自定义名称空间。构建贴图APK时,aapt2(链接)会抛出“找不到属性”错误。

如何知道从主应用程序到叠加层的自定义属性?
甚至可以在叠加层中使用自定义属性吗?

详细信息:
覆盖包含两个文件:

AndroidManifest.xml:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<input type="file" id="filepicker" name="fileList" webkitdirectory multiple />
<div id="listing">
</div>

<script>
//This is the array or list of file names which are already available. If I select the same name file again,It will match. If Matched,remove that selected file from this Multiple Selected files. Means this file will not upload again

var filesBuffer = ["545-1 CHARLI MUSCAT - SC_106 8 U REST HIP HOP.mp3","545-1 CHARLI MUSCAT - SC_106 8 U REST HIP HOP.mp3","530-1 CHARLI MUSCAT - SC_100 8 U COMBINED STRAIGHT WALTZ TAP.mp3"];

function findValueInArray(value,arr){
  var result = "0";
 
  for(var i=0; i<arr.length; i++){
    var name = arr[i];
    if(name == value){
      result = '1';
      break;
    }
  }

  return result;
}

$('#filepicker').change(function(event){
    var qty = event.target.files.length;
          for(i=0; i<qty; ++i){
        var fileName = event.target.files[i].name;
        var res = findValueInArray(fileName,filesBuffer);
        if(res == 0){
        $("#listing").append(fileName+'<br>');
        
        }else{
            //Here I want to remove the file from the Files selected in input field But I am getting error on this line only. Only this line need to be updated with a code to remove the matched file
            $('#filepicker').target[i].val('');
        }
    } 
});
</script>

和xml文件res / xml / my_config.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>

主应用程序在res / values / attrs.xml中定义属性 text

<?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 / values / overlayable.xml中定义了可覆盖标签:

...
<declare-styleable name="MyConfig">
    <attr name="text" format="string" />
</declare-styleable>

要构建叠加层,请执行以下操作:

aapt2编译-v --dir app / src / main / res / -o SimpleAppOverlay.flata

aapt2链接-v --no-resource-removal
-I〜/ Library / Android / sdk / platforms / android-29 / android.jar
--manifest app / src / main / AndroidManifest.xml
-o sao.apk SimpleAppOverlay.flata

这将导致以下输出:

注意:包括/Users/bernd/Library/Android/sdk/platforms/android-29/android.jar
aapt2 W 09-01 14:33:06 20083 694697 ApkAssets.cpp:138] APK'/Users/bernd/Library/Android/sdk/platforms/android-29/android.jar'中的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:错误:属性文本(又名 de.test.simpleappoverlay:text)找不到
错误:链接文件资源失败。

解决方法

我遇到了与此类似的问题,我试图在 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-auto”,它将无法正常工作,因为它解析为您的应用程序名称(在本例中为覆盖应用程序 de.test.simpleappoverlay),其中不包含私有属性的定义。

第 2 部分

由于您现在在链接时依赖于主应用程序,因此您必须使用 -I simpleapp.apk(或任何基础应用程序的 APK 名称)将其包含在链接命令中。现在你只是在 aapt2 链接步骤中包含 android.jar,它只包含 'android' 命名空间和属性。因此,您现在需要在包含步骤中添加您的基础应用程序,以便它可以根据其命名空间和属性正确链接。

就像其他一些答案所说的那样,这个问题在 Android 11 中消失了,但如果你像我一样坚持使用 Android 10,我希望这会有所帮助。

,

我认为 RRO 的当前实现(至少在 Android Q 中)不支持包含新 ID。 关于您的错误,aapt 使用 android.jar 为您的叠加层生成 apk。由于它找不到您的新属性,因此会引发错误。为此,我相信您需要使用修改后的 android.jar 包括您的属性。一种方法是修改 AOSP 中的 Android SDK 并创建您自己的版本,然后将其用于 aapt 命令。

,

前段时间我将我的 AOSP 环境从 Android 10 切换到 11。Google 对 Overlay 机制进行了很​​多更改。令我惊讶的是,这些更改解决了我在尝试“覆盖”自定义属性时遇到的问题。
在 Android 10 环境中,我在调试时观察到 Android XML 解析器在尝试读取上述属性时返回“null”。使用 idmap,我能够确认属性存在于覆盖层和目标应用程序中,并且它们被正确映射。
此外,所有链接器错误都消失了。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...