密钥必须是特定于应用程序的资源ID

时间:2010-05-18 17:32:14

标签: android illegalargumentexception

为什么我会收到此异常?

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;

10 个答案:

答案 0 :(得分:212)

你无法使用setTag(int,Object)的原因是因为android需要在'int'参数中预编译唯一id。

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

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

答案 1 :(得分:137)

我参加派对有点晚了,但我今天自己偶然发现了这个问题并认为我也会给出答案。这个答案将是对其他答案的汇编,但有一点扭曲。首先,正如其他人所指出的那样,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中。

答案 2 :(得分:49)

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

如果视图只包含一个标记,则可以执行

setTag(objContact.onlineid);

答案 3 :(得分:47)

这将是工作......

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

如果您有2个或更多具有不同键的setTag,则会出现问题。 我的意思是:

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

那种情况是错误的。然后,您需要添加一个名为maybe 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, KEY_1)
 setTag(R.id.imageURI, KEY_2)
 ...

答案 4 :(得分:7)

private static final int TAG_ONLINE_ID = 1 + 2 << 24;

应该有效。来自ceph3us的更多信息:

  

指定的密钥应该是在资源中声明的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);
}

答案 5 :(得分:3)

我使用了viewHolder.itemTitleTextView.getId()。但您也可以在资源中声明: <item type="id" name="conversation_thread_id"/>

答案 6 :(得分:1)

您希望按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

答案 7 :(得分:0)

这对我有用:

setTag(0xffffffff,objContact.onlineid);

答案 8 :(得分:0)

您可以使用此:

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

获取特定于应用程序的唯一资源ID

答案 9 :(得分:0)

这是一个对我有用的简单解决方法:

int tagKey = "YourSimpleKey".hashCode();

myView.setTag(tagKey, "MyTagObject");

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