【问题标题】:The key must be an application-specific resource id键必须是特定于应用程序的资源 ID
【发布时间】:2011-02-21 00:30:35
【问题描述】:

为什么我会得到这个异常?

05-18 20:29:38.044: ERROR/AndroidRuntime(5453): java.lang.IllegalArgumentException: The key must be an application-specific resource id.
05-18 20:29:38.044: ERROR/AndroidRuntime(5453):     at android.view.View.setTag(View.java:7704)
05-18 20:29:38.044: ERROR/AndroidRuntime(5453):     at com.mypkg.viewP.inflateRow(viewP.java:518)

有问题的行是:

((Button) row.findViewById(R.id.btnPickContact)).setTag(TAG_ONLINE_ID,objContact.onlineid);

我将其定义为:

private static final int TAG_ONLINE_ID = 1;

【问题讨论】:

    标签: android illegalargumentexception


    【解决方案1】:

    您不能使用 setTag(int, Object) 的原因是 android 需要在 'int' 参数中预编译的唯一 ID。

    尝试在 String.xml xml 中创建两个唯一条目,例如“firstname”和“secondname”,并如下使用它们

    imageView.setTag(R.string.firstname, "Abhishek");
    imageView.setTag(R.string.lastname, "Gondalia");
    

    【讨论】:

    • 将此添加到您的 strings.xml 文件中: 您可以像使用常规 id 资源一样使用:R.id.TAG_ONLINE_ID
    • 这个应该是答案。它更通用。
    • @AjithMemana 为什么?编译应用程序时,strings.xml 文件为每个元素分配一个唯一的 int 资源 ID。不考虑字符串元素的值。
    • 谢谢你,这太棒了,很有帮助......如果你想获得标签,你需要访问像 v.getTag(R.string.name) 这样的字符串值
    • 最好在 res/values 目录中创建一个文件名 ids.xml 并在那里添加你所有的唯一 ID。
    【解决方案2】:

    我参加聚会有点晚了,但我今天自己偶然发现了这个问题,并认为我也会给出答案。这个答案将是其他答案的汇编,但有所不同。首先,正如其他人所指出的,id 不能是您的代码中定义的常量(例如 private static final int MYID = 123)或您在某处定义为字段的任何其他 int。

    id 必须是预编译的唯一 id,就像您在 values/strings.xml 中获得的字符串一样(即 R.string.mystring)。请参阅http://developer.android.com/guide/topics/resources/available-resources.htmlhttp://developer.android.com/guide/topics/resources/more-resources.html 了解更多信息。

    我的建议是创建一个名为 values/tags.xml 的新文件并写入:

        <resources xmlns:android="http://schemas.android.com/apk/res/android">
          <item name="TAG_ONLINE_ID" type="id"/>
        </resources>
    

    我认为最好创建一个单独的文件,而不是像 EtienneSky 建议的那样将其放在 strings.xml 中。

    【讨论】:

    • 您甚至可以将其发送至&lt;item name="TAG_ONLINE_ID" type="id"/&gt; 以简化。
    • 这是真正的解决方案;不是新手“我不明白我在做什么,但这个 hack 有效”-解决方案
    • 注意,要在代码中访问使用R.id...,而 R.string..R.tags...
    • 这很有用,这里是另一篇展示其用法的帖子:stackoverflow.com/questions/28492493/…
    • 并确保将文件放在值中,而不是放在 xml 文件夹中。 :)
    【解决方案3】:

    这样就可以了……

    如果你的类中只有 1 个 setTag,你可以使用任何 int,也许是在顶部声明的 static final。

    当您有 2 个或更多具有不同键的 setTag 时,问题就出现了。 我的意思是:

    public static final int KEY_1 = 1;
    public static final int KEY_2 = 2;
    ...
    setTag(KEY_1, VALUE_1)
    setTag(KEY_2, VALUE_2)
    ...
    

    这种情况是错误的。然后,您需要添加一个名为也许 ids.xml 的值文件,其中包含以下内容:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <item type="id" name="resourceDrawable" />
        <item type="id" name="imageURI" />
    </resources>
    

    然后,在你的课堂上,调用:

     ...
     setTag(R.id.resourceDrawable, VALUE_1)
     setTag(R.id.imageURI, VALUE_2)
     ...
    

    【讨论】:

    • 对新手的最佳解释
    • 这是真正的解决方案:不是新手破解补丁!
    • 为什么要调用你存储的值“KEY_..”?有点混淆了解释。
    • @sb4 将答案更改为使用 VALUE_ 而不是 KEY_
    【解决方案4】:

    标签 id 必须是唯一的,因此它希望它是在资源文件中创建的 id 以保证唯一性。

    如果视图只包含一个标签,但你可以这样做

    setTag(objContact.onlineid);
    

    【讨论】:

    • 我还是不明白这个模式。我想设置两个标签,分别对应名字和姓氏。我在哪里为这些定义整数 ID?
    • 您可以使用任何资源 - 甚至只是随机选择一个 R.id.FOO,其中 FOO 是您项目中的某个 id。
    • 这是获得唯一标签 ID 的最佳方式吗?真的是安卓吗?
    • 嘿,如果我不知道有多少标签怎么办?因为我想根据模型中的一些数据生成视图......
    • 提问者问题的可能解决方案,但不是最佳解决方案。不应标记为答案...
    【解决方案5】:
    private static final int TAG_ONLINE_ID = 1 + 2 << 24;
    

    应该可以。更多信息来自ceph3us

    指定的key应该是在资源中声明的id 应用程序,以确保它是唯一的密钥标识为属于 Android 框架或未关联任何包将导致 抛出 IllegalArgumentException。

    来源:

    public void setTag(int key, final Object tag) {
        // If the package id is 0x00 or 0x01, it's either an undefined package
        // or a framework id
        if ((key >>> 24) < 2) {
            throw new IllegalArgumentException("The key must be an application-specific "
                    + "resource id.");
        }
    
        setKeyedTag(key, tag);
    }
    

    【讨论】:

    • 因为 ID 必须是在您的 R.java 文件中生成的 ID。
    • 不,它没有。它必须大于 2
    • 嗯,1 + 2
    • 因为它在 Android SDK 中是硬编码的。它永远不会改变,否则所有现有的 Android 应用程序都将停止工作。
    • 我猜这个解决方案的主要问题是它不保证这个键的唯一性,这意味着通过添加一些使用 setTag 功能的库或其他代码,如果生成的 id 会破坏这个逻辑从这个解决方案中得到的匹配项。
    【解决方案6】:

    我用过viewHolder.itemTitleTextView.getId()。但是你也可以在你的资源中声明: &lt;item type="id" name="conversation_thread_id"/&gt;

    【讨论】:

      【解决方案7】:

      你可以用这个:

      private static final int TAG_ONLINE_ID = View.generateViewId() + 2 &lt;&lt; 24;

      用于 uniqness 应用程序特定的资源 ID

      【讨论】:

        【解决方案8】:

        这对我有用:

        setTag(0xffffffff,objContact.onlineid);
        

        【讨论】:

          【解决方案9】:

          你想用 id 保存值的原因是,你想在这个标签中覆盖多个值,对吧?
          这里有一个更简单的解决方案:
          假设您想将两个值(字符串)保存到此标签中:“firstname”和“lastname”。您可以将它们保存在一个字符串中,用分号分隔:

          v.setTag(firstname + ";" + lastname);
          

          ...并通过将它们拆分为字符串数组来访问它们:

          String[] data = v.getTag().toString().split(";");
          System.out.println(data[0]) //firstname
          System.out.println(data[1]) //lastname
          

          【讨论】:

            【解决方案10】:

            这是一个适合我的简单解决方法:

            int tagKey = "YourSimpleKey".hashCode();
            
            myView.setTag(tagKey, "MyTagObject");
            

            这里的重要线索是在字符串上调用.hashCode();

            【讨论】:

              猜你喜欢
              • 2012-09-08
              • 2011-03-06
              • 1970-01-01
              • 2012-11-26
              • 1970-01-01
              • 2019-11-05
              • 2018-11-13
              • 2011-08-20
              • 1970-01-01
              相关资源
              最近更新 更多