Der Schlüssel muss eine anwendungsspezifische Ressourcen-ID sein


145

Warum bekomme ich diese Ausnahme?

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)

Die fragliche Zeile lautet:

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

und ich habe es definiert als:

private static final int TAG_ONLINE_ID = 1;

Antworten:


55

Die Tag-ID muss eindeutig sein, damit sie in einer Ressourcendatei erstellt wird, um die Eindeutigkeit zu gewährleisten.

Wenn die Ansicht nur ein Tag enthält, können Sie dies einfach tun

setTag(objContact.onlineid);

3
Ich verstehe das Muster immer noch nicht. Ich möchte zwei Tags setzen, die einem Vor- und Nachnamen entsprechen. Wo definiere ich die Integer-IDs für diese?
Jeffrey Blattman

7
Sie können jede Ressource verwenden - nehmen Sie einfach eine zufällige R.id.FOO, wobei FOO eine ID in Ihrem Projekt ist.
Artem Russakovskii

16
Das ist der beste Weg, um eine eindeutige Tag-ID zu erhalten? Wirklich Android?
Jimmy0251

Hey, was ist, wenn ich nicht weiß, wie viele Tags es gibt? weil ich Ansichten gemäß einigen Daten im Modell erzeugen möchte ....
jsina

Eine mögliche Lösung für das Problem des Fragestellers, aber nicht die beste Lösung. Sollte nicht als Antwort markiert werden ...
AngryITguy

226

Der Grund, warum Sie setTag (int, Object) nicht verwenden können, ist, dass Android eine vorkompilierte eindeutige ID im Argument 'int' benötigt.

Versuchen Sie, zwei eindeutige Einträge in String.xml xml zu erstellen, z. B. "Vorname" und "Nachname", und verwenden Sie sie wie folgt

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

129
Fügen Sie dies zu Ihrer Datei strings.xml hinzu: <item type = "id" name = "TAG_ONLINE_ID" /> und Sie können wie eine normale ID-Ressource verwenden: R.id.TAG_ONLINE_ID
EtienneSky

9
Dieser sollte die Antwort sein. es ist allgemeiner.
IronBlossom

2
@ AjithMemana warum? Wenn die App kompiliert wird, weist die Datei strings.xml jedem Element eine eindeutige int-Ressourcen-ID zu. Der Wert des Zeichenfolgenelements wird nicht berücksichtigt.
Ataulm

1
Vielen Dank, das ist so großartig und hilfreich ... auch wenn Sie das Tag erhalten möchten, müssen Sie auf Zeichenfolgenwerte wie v.getTag (R.string.name)
zugreifen

5
Erstellen Sie besser einen Dateinamen ids.xml im Verzeichnis res / values und fügen Sie dort alle Ihre eindeutigen IDs hinzu.
Vovahost

146

Ich bin etwas spät zur Party, aber ich bin heute selbst auf dieses Problem gestoßen und dachte, ich würde auch eine Antwort geben. Diese Antwort wird eine kleine Zusammenstellung der anderen Antworten sein, aber mit einer Wendung. Erstens kann die ID, wie von anderen erwähnt, KEINE in Ihrem Code definierte Konstante sein (z. B. private static final int MYID = 123) oder eine andere int, die Sie irgendwo als Feld definieren.

Die ID muss eine vorkompilierte eindeutige ID sein, genau wie die, die Sie für Zeichenfolgen erhalten, die Sie in values ​​/ strings.xml (dh R.string.mystring) eingeben. Weitere Informationen finden Sie unter http://developer.android.com/guide/topics/resources/available-resources.html und http://developer.android.com/guide/topics/resources/more-resources.html .

Mein Vorschlag ist, dass Sie eine neue Datei mit dem Namen values ​​/ tags.xml erstellen und schreiben:

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

Ich denke, es ist besser, eine separate Datei zu erstellen, als sie in die Datei strings.xml zu legen, wie EtienneSky vorgeschlagen hat.


14
Sie können es sogar <item name="TAG_ONLINE_ID" type="id"/>vereinfachen.
Benoit Duffez

Dies ist die wirkliche Lösung; Nicht der Neuling "Ich verstehe nicht, was ich tue, aber dieser Hack funktioniert" -Lösung
Roel

Beachten Sie, um in Code-Verwendung zuzugreifen R.id..., und nicht R.string.. oderR.tags...
g2server

Dies war nützlich und hier ist ein weiterer Beitrag, in dem seine Verwendung gezeigt wird: stackoverflow.com/questions/28492493/…
prasad_

Und stellen Sie sicher, dass Sie die Datei in den Werten und nicht im XML-Ordner ablegen. :)
Nantoka

55

DAS WIRD DEN JOB TUN ...

Wenn Sie nur 1 setTag in Ihrer Klasse haben, können Sie ein beliebiges int verwenden, möglicherweise ein statisches Finale, das oben deklariert ist.

Das Problem tritt auf, wenn Sie zwei oder mehr setTags mit unterschiedlichen Schlüsseln hatten. Ich meine:

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

Dieses Szenario ist falsch. Anschließend müssen Sie eine Wertedatei mit dem Namen "Vielleicht ids.xml" hinzufügen:

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

Rufen Sie dann in Ihrer Klasse an:

 ...
 setTag(R.id.resourceDrawable, KEY_1)
 setTag(R.id.imageURI, KEY_2)
 ...

beste Erklärung für Neuankömmlinge
Richard Le Mesurier

Dies ist die wirkliche Lösung: nicht der Newbie Hack Fix!
Roel

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

sollte arbeiten. Weitere Infos von ceph3us :

Der angegebene Schlüssel sollte eine ID sein, die in den Ressourcen der Anwendung deklariert ist, um sicherzustellen, dass es sich um eindeutige Schlüssel handelt, die als zum Android-Framework gehörend oder keinem Paket zugeordnet identifiziert werden. Dies führt dazu, dass eine IllegalArgumentException ausgelöst wird.

aus der Quelle:

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);
}

Weil die ID eine sein muss, die in Ihrer R.java-Datei generiert wurde.
StackOverflowed

Nein, tut es nicht. Es muss größer als 2 << 24 sein, das ist alles.
Anton Duzenko

Nun, der Ansatz 1 + 2 << 24, 2 + 2 << 24 usw. funktioniert tatsächlich. Sieht aus wie eine unregelmäßige Lösung. Ich möchte wissen, warum es so ist? Gibt es Risiken, zum Beispiel in zukünftigen Versionen von Android usw.? Es ist bei weitem ersticken, es als Konstante definiert zu verwenden?
Jan Bergström

Weil es im Android SDK fest codiert ist. Es wird sich nie ändern, da sonst alle vorhandenen Android-Apps nicht mehr funktionieren.
Anton Duzenko

1
Ich denke, das Hauptproblem bei dieser Lösung besteht darin, dass die Eindeutigkeit dieses Schlüssels nicht garantiert wird. Dies bedeutet, dass durch Hinzufügen einer Bibliothek oder eines anderen Codes, der die setTag-Funktion verwendet, diese Logik unterbrochen werden kann, wenn die generierte ID mit der aus dieser Lösung erhaltenen übereinstimmt.
EdgarK

3

Ich habe benutzt viewHolder.itemTitleTextView.getId(). Sie können aber auch in Ihren Ressourcen deklarieren: <item type="id" name="conversation_thread_id"/>


0

Das funktioniert bei mir:

setTag(0xffffffff,objContact.onlineid);

0

Der Grund, warum Sie den Wert durch eine ID speichern möchten, ist, dass Sie mehr als einen Wert in diesem Tag abdecken möchten, oder?
Hier eine einfachere Lösung:
Angenommen, Sie möchten zwei Werte (Strings) in diesem Tag speichern: "Vorname" und "Nachname". Sie können beide in einer durch Semikolon getrennten Zeichenfolge speichern:

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

... und greifen Sie darauf zu, indem Sie sie in ein String-Array aufteilen:

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

0

Sie können dies verwenden:

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

für Uniqness anwendungsspezifische Ressourcen-ID

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.