2012-04-29 7 views
6

Also, ich habe Code, der IDs für eine Anzahl von Elementen mit einem AtomicInteger erzeugt, der standardmäßig auf Integer.MAX_VALUE gesetzt ist und von dort mit jedem dekrementiert wird Ansicht, der eine ID zugewiesen wird. So wäre die erste Ansicht mit einer generierten ID Integer.MAX_VALUE - 1, die zweite wäre Integer.MAX_VALUE - 2, usw. Das Problem, vor dem ich Angst habe, ist eine Kollision mit IDs, die von Android in R.java erzeugt werden.Überprüfung, ob eine ID in Ressourcen existiert (R.id.etwas)

Also meine Frage ist, wie kann ich feststellen, ob eine ID bereits verwendet wird und überspringe es, wenn ich die IDs erzeuge. Ich erstelle nur maximal 30 IDs, also ist das keine große Priorität, ich möchte das so fehlerfrei wie möglich machen.

Antwort

9

Der folgende Code wird Ihnen sagen, ob die Kennung eine ID ist oder nicht.

static final String PACKAGE_ID = "com.your.package.here:id/" 
... 
... 
int id = <your random id here> 
String name = getResources().getResourceName(id); 
if (name == null || !name.startsWith(PACKAGE_ID)) { 
    // id is not an id used by a layout element. 
} 
+0

Danke! Das sieht vielversprechend aus. Ich habe nicht einmal daran gedacht, getResources zu verwenden. Ich werde es ausprobieren. – Brandon

+0

@Brandon, sollten Sie Ihre Frage aktualisieren, wenn Sie etwas mehr hinzuzufügen haben. Wenn du deinen Schnitt betrachtest, wird er sogar noch besser als Antwort auf deine eigene Frage sein! – Ben

+4

'name' wird niemals' null' sein. Stattdessen wird '' Resources.NotFoundException' 'durch 'getResourceName()' ausgelöst, wenn der Bezeichner ungültig ist – sfera

0

Nur eine Idee ... Sie könnten die findViewById (int id) verwenden, um zu überprüfen, ob die id bereits verwendet wird.

+2

das würde nur funktionieren, wenn der Kontext auf die bestimmte Ansicht festgelegt wurde, die die ID gefunden wurde. Mit anderen Worten mit mehr als einer Ansicht und verschiedenen IDs, die niemals als Erkennung funktionieren würden. – MikeIsrael

1

Sie können Java Reflection API verwenden, um auf Elemente zuzugreifen, die in einem Objekt der Klasse R.id vorhanden sind.

Der Code ist wie folgt:

Class<R.id> c = R.id.class; 

R.id object = new R.id(); 

Field[] fields = c.getDeclaredFields(); 

// Iterate through whatever fields R.id has 
for (Field field : fields) 
{ 
    field.setAccessible(true); 

    // I am just printing field name and value, you can place your checks here 

    System.out.println("Value of " + field.getName() + " : " + field.get(object)); 
} 
+0

Das sieht so aus, als könnte es funktionieren, aber ich entschied mich für @Jens Antwort – Brandon

3

Ich modifizierte Jens Antwort von oben seit, wie in den Kommentaren angegeben, Name wird nie null und Ausnahme wird stattdessen geworfen.

private boolean isResourceIdInPackage(String packageName, int resId){ 
    if(packageName == null || resId == 0){ 
     return false; 
    } 

    Resources res = null; 
    if(packageName.equals(getPackageName())){ 
     res = getResources(); 
    }else{ 
     try{ 
      res = getPackageManager().getResourcesForApplication(packageName); 
     }catch(PackageManager.NameNotFoundException e){ 
      Log.w(TAG, packageName + "does not contain " + resId + " ... " + e.getMessage()); 
     } 
    } 

    if(res == null){ 
     return false; 
    } 

    return isResourceIdInResources(res, resId); 
} 

private boolean isResourceIdInResources(Resources res, int resId){ 

    try{    
     getResources().getResourceName(resId); 

     //Didn't catch so id is in res 
     return true; 

    }catch (Resources.NotFoundException e){ 
     return false; 
    } 
} 
Verwandte Themen