2012-04-29 28 views
6

Vì vậy, tôi có mã tạo ID cho một số thành phần sử dụng AtomicInteger được đặt theo mặc định tại Integer.MAX_VALUE và được giảm từ đó với mỗi phần tử chế độ xem được chỉ định ID. Vì vậy, quan điểm đầu tiên với một ID được tạo ra sẽ là Integer.MAX_VALUE - 1, thứ hai sẽ là Integer.MAX_VALUE - 2, v.v. Vấn đề tôi sợ là một vụ va chạm với ID được tạo bởi Android trong R.java.Kiểm tra xem ID có tồn tại trong tài nguyên (R.id.something)

Vì vậy, câu hỏi của tôi là làm thế nào tôi có thể phát hiện nếu một ID đã được sử dụng và bỏ qua nó khi tôi tạo ID. Tôi chỉ tạo ra tối đa 30 ID vì vậy đây không phải là một hạt có mức độ ưu tiên lớn mà tôi muốn làm cho lỗi này miễn phí nhất có thể.

Trả lời

9

Đoạn mã dưới đây sẽ cho bạn biết nếu nhận dạng là một id hay không.

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

Cảm ơn! Điều này có vẻ đầy hứa hẹn. Tôi thậm chí không nghĩ đến việc sử dụng getResources. Tôi se thử no. – Brandon

+0

@ Brandon, bạn nên cập nhật câu hỏi của mình nếu bạn có thêm thứ gì đó để thêm. Nhìn vào chỉnh sửa của bạn mặc dù nó sẽ còn tốt hơn như một câu trả lời cho câu hỏi của riêng bạn! – Ben

+4

'name' sẽ không bao giờ là' null'. thay vào đó, một 'Resources.NotFoundException' sẽ được ném bởi' getResourceName() 'nếu mã định danh không hợp lệ – sfera

0

Chỉ cần một ý tưởng ... bạn có thể sử dụng findViewById (int id) để kiểm tra xem id đã được sử dụng chưa.

+2

chỉ hoạt động nếu ngữ cảnh được đặt thành chế độ xem cụ thể mà id được đặt. Nói cách khác, có nhiều hơn một chế độ xem và các id khác nhau sẽ không bao giờ hoạt động như phát hiện. – MikeIsrael

1

Bạn có thể sử dụng Java Reflection API để truy cập bất kỳ yếu tố nào có mặt trong đối tượng của lớp R.id.

Mã này là như thế này:

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

Điều này có vẻ như nó có thể hoạt động nhưng tôi quyết định đi với @Jens answer – Brandon

3

Tôi đã sửa đổi câu trả lời Jens từ trên, như đã nêu trong nhận xét, tên sẽ không bao giờ là rỗng và ngoại lệ được ném thay thế.

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; 
    } 
} 
Các vấn đề liên quan