키는 응용 프로그램 특정 자원 ID 여야합니다.


145

이 예외가 발생하는 이유는 무엇입니까?

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;

답변:


55

태그 ID는 고유해야하므로 고유성을 보장하기 위해 자원 파일에서 작성된 ID가 되길 원합니다.

뷰에 태그가 하나만 포함되어 있다면

setTag(objContact.onlineid);

3
나는 여전히 패턴을 얻지 못한다. 이름과성에 해당하는 두 개의 태그를 설정하고 싶습니다. 이들에 대한 정수 ID를 어디에서 정의합니까?
Jeffrey Blattman

7
모든 리소스를 사용할 수 있습니다. 심지어 임의의 R.id.FOO를 가져와도됩니다. 여기서 FOO는 프로젝트의 일부 ID입니다.
Artem Russakovskii

16
이것이 고유 한 태그 ID를 얻는 가장 좋은 방법입니까? 정말 안드로이드?
jimmy0251

이봐, 얼마나 많은 태그가 있는지 모르겠다면? 모델의 일부 데이터에 따라 뷰를 생성하고 싶기 때문에 ...
jsina

asker의 문제점에 대한 가능한 솔루션이지만 최상의 솔루션은 아닙니다. 대답으로 표시해서는 안됩니다 ...
angryITguy

226

setTag (int, Object)를 사용할 수없는 이유는 안드로이드가 'int'인수에 미리 컴파일 된 고유 ID를 요구하기 때문입니다.

String.xml xml에서 "firstname"& "secondname"이라는 두 개의 고유 한 항목을 만들어 아래처럼 사용하십시오.

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

129
<항목 유형 = "ID"이름 = "TAG_ONLINE_ID을"/> 당신은 정기적으로 ID를 자원처럼 사용할 수 있습니다 : 당신의 strings.xml의 파일이 추가 R.id.TAG_ONLINE_ID
EtienneSky에게

9
이것이 답이되어야합니다. 더 일반적입니다.
IronBlossom

2
@AjithMemana 왜? 앱이 컴파일되면 strings.xml 파일은 각 요소에 고유 한 int 리소스 ID를 할당합니다. 문자열 요소의 값은 고려되지 않습니다.
ataulm 2016 년

1
고맙습니다. 너무 훌륭하고 도움이됩니다 ... 또한 태그를 얻으려면 v.getTag (R.string.name)와 같은 문자열 값에 액세스해야합니다
Amt87

5
res / values 디렉토리 에 파일 이름 ids.xml 을 더 잘 작성하고 모든 고유 ID를 추가하십시오.
vovahost

146

나는 파티에 조금 늦었지만 오늘이 문제에 걸려 넘어져서 답을 줄 것이라고 생각했다. 이 답변은 다른 답변을 약간 편집 한 것이지만 꼬인 것입니다. 우선, 다른 사람들이 지적한 것처럼 id는 코드 (예 : private static final int MYID = 123) 또는 필드로 정의하는 다른 int로 정의 된 상수가 될 수 없습니다.

id는 values ​​/ strings.xml에 넣은 문자열 (예 : R.string.mystring)과 마찬가지로 미리 컴파일 된 고유 ID 여야합니다. 자세한 내용은 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에 넣는 대신 별도의 파일을 만드는 것이 좋습니다.


14
<item name="TAG_ONLINE_ID" type="id"/>단순화하기 위해 만들 수도 있습니다 .
Benoit Duffez

이것이 실제 솔루션입니다. 초보자가 아닙니다 "내가하는 일을 이해하지 못하지만이 해킹은 효과가 있습니다"
Roel

노트, 코드 사용에 액세스 R.id...하고, 하지 R.string.. 또는R.tags...
g2server

이것은 유용했고 여기에 그 사용법을 보여주는 또 다른 게시물이 있습니다 : stackoverflow.com/questions/28492493/…
prasad_

그리고 파일을 xml 폴더가 아닌 값에 넣으십시오. :)
Nantoka 2016 년

55

이 작업을 수행합니다 ...

클래스에 1 개의 setTag 만 있으면 상단에 선언 된 정적 최종 결과를 사용할 수 있습니다.

다른 키를 가진 2 개 이상의 setTag가있을 때 문제가 발생합니다. 내말은:

public static final int KEY_1 = 1;
public static final int KEY_2 = 2;
...
setTag(KEY_1)
setTag(KEY_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, KEY_1)
 setTag(R.id.imageURI, KEY_2)
 ...

초보자를위한 최고의 설명
Richard Le Mesurier

이것은 실제 해결책입니다. 초보 해킹 수정이 아닙니다!
Roel

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

작동해야합니다. ceph3us의 추가 정보 :

지정된 키는 Android 프레임 워크에 속하는 것으로 식별되거나 패키지와 연관되지 않은 고유 키인지 확인하려면 애플리케이션의 자원에서 선언 된 ID 여야합니다. 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 파일에서 생성되어야하기 때문에.
StackOverflowed

아니 그렇지 않아. 2 << 24보다 커야합니다.
Anton Duzenko

1 + 2 << 24, 2 + 2 << 24 등의 접근법은 실제로 작동합니다. 불규칙한 수정처럼 보입니다. 왜 이런지 알고 싶어요? 예를 들어 향후 Android 버전 등의 위험이 있습니까? 상수로 정의 된 것을 사용하는 것이 훨씬 질식입니까?
Jan Bergström

Android SDK로 하드 코딩되어 있기 때문입니다. 그렇지 않으면 기존의 모든 안드로이드 앱이 작동을 멈추기 때문에 변경되지 않습니다.
Anton Duzenko

1
이 솔루션의 주요 문제는이 키의 고유성을 보장하지 않는다는 것입니다. 즉 setTag 기능을 사용하는 라이브러리 또는 다른 코드를 추가하면 생성 된 id 가이 솔루션에서 얻은 것과 일치하면이 논리가 중단 될 수 있습니다.
EdgarK

3

사용했습니다 viewHolder.itemTitleTextView.getId(). 그러나 당신은 또한 당신의 자원에서 선언 할 수 있습니다 : <item type="id" name="conversation_thread_id"/>



0

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

0

당신은 이것을 사용할 수 있습니다 :

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

uniqness 응용 프로그램 특정 자원 ID

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.