8 Nisan 2012 Pazar

Farklı projelerde JAR library'de tanımlanmış android resource dosyalarını kullanmak

Merhaba, uzun bir aradan sonra yeni bir makaleyle tekrar beraberiz. Başlık biraz garip oldu ama anlatmak istediğim şeyi daha farklı nasıl yazarım bilemedim. Problemimiz şu: Farklı projelerde kullanmak amacıyla kendi library'inizi (jar dosyanızı) oluşturduğunuzu varsayalım. Eğer paket içinde herhangi bir android resource dosyası mevcutsa maalesef bu kütüphaneyi import ettiğinizde hata ile karşılaşacaksınız. Bunun nedeni resource dosyalarının final static olarak tanımlanması ve her projenin "R"esource'unun diğerlerinden farklı olmasından kaynaklanmaktadır. Hemen basit bir örnek.

Diyelim ki kütüphanenizde showToast adinda kendinize özel geliştirdiğiniz bir method var. Bu method adından da anlaşılacağı üzere kullanıcıya mesaj vermek için oluşturduğunuz bir method. Gösterilen mesajda öyleya sadece strings.xml resource'unda tanımlı MESAJ_DESC adındaki parametreye ne tanımlanmışsa onu gösteriyor diyelim. Doğal olarak istediğiniz şey, bu kütüphaneyi kullandığınız her projede strings.xml'deki MESAJ_DESC parametresini özelleştirebilmek olacak. Ancak MESAJ_DESC parametresinin ID'sinde bulunan değer, kütüphanenin oluşturulduğu projenin Resource dosyasında neyse her zaman o olacağından uygulama MESAJ_DESC parametresini bulamayacak, hata verecek ve bu library'i kullanamayacaksınız. İşte bu gibi durumlarda aşağıdaki method ile bu problemin önüne geçmeniz mümkün.
public static int getResourceIdByName(String packageName, String className, String name) {
   Class r = null;
   int id = 0;
try {
    r = Class.forName(packageName + ".R");

    Class[] classes = r.getClasses();
    Class desireClass = null;

    for (int i = 0; i < classes.length; i++) {
        if(classes[i].getName().split("\\$")[1].equals(className)) {
            desireClass = classes[i];

            break;
        }
    }

    if(desireClass != null)
        id = desireClass.getField(name).getInt(desireClass);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (SecurityException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}
return id;
}
Kullanımı için
int id = getResourceIdByName(context.getPackageName(), "string", "showToast");
(Kaynak: http://stackoverflow.com/questions/1995004/packaging-android-resource-files-within-a-distributable-jar-file)

Hiç yorum yok:

Yorum Gönder