키는 응용 프로그램 특정 자원 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.html 및 http://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.