android etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
android etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

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)

4 Şubat 2012 Cumartesi

Android ile Reflection (Android and Reflection)

Merhaba, (Hello)

Android ile ilgili yazılarımıza "reflection - yansıma" konusuyla devam ediyoruz. Aslında bu konuyu android için özelleştirmek çok mantıklı olmasa da android ile ilgili yazılan türkçe makaleler arasında örnek teşkil etmesi bakımından değinmek faydalı olacaktır diye düşünüyorum. Keza reflection zaten gerek java gerekse de .net geliştiricilerinin zaman zaman projelerinde kullandıkları önemli bir kütüphane. Dilerseniz konuyu biraz daha genel boyuta taşıyarak -bilakis daha önceden hiç kullanma fırsatı olmayan arkadaşlar için- kısa bir şekilde reflection'ın ne olduğu ve ne işe yaradığından bahsederek başlayalım. Reflection çok basit anlamda, herhangi bir nesnenin üye elemanlarına çalışma zamanında (runtime) ulaşıp, bu elemanların çağrılmalarına (invoking) imkan veren yapıdır. Reflection'ın avantaj ve dezavantajlarına girmek istemiyorum, internette bir çok kaynaktan bunları zaten detaylıca öğrenmek mümkün yalnız konumuz dışında olsa da belirtmekte fayda gördüğüm iki madde olacak. Bunlardan ilki reflection konusunda C# ile Java arasında bilinmesi gereken belki de en temel farklılık ile ilgili.
(We are continuing to talk about android with the "Reflection". Basically there are a lot of C# or Java developers who work with it on their projects time to time so it's a keypoint for both side not just Android. In a very simple manner the reflection is the ability to discover the members of a class and to invoke methods at runtime. I don't want to talk about advantages or disadvantages of the reflection because there are a few sources that may help you to lead what is it about on the internet but for a general knowledge I would like to mention two important things about differences between c# and java reflection)
  1. C#'ta reflection assembly seviyesinde olmaktayken, Java'da class seviyesinde uygulanmaktadır. .NET'te assemblyler dll'lerde tutulduğundan dolayı assembly load edilerek yapılırken java da class'ın kendisine erişim sağlanarak gerçekleştirilir. (Reflection in C# is done at the assembly level while reflection in Java is done at the class level. Since assemblies are typically stored in DLLs, one needs the DLL containing the targeted class to be available in C# while in Java one needs to be able to load the class file for the targeted class.)
  2. .NET'te ilgili nesnenin metadatası System.Type nesnesinde enkapsüle edilirken Java'da java.lang.Class nesnesi içerisinde enkapsüle edilir. (To retrieve the metadata class from an instance of the target class, the getClass() method is used in Java while the GetType() method is used in C#)
Type x = typeOf(y); // C# 
Class x = y.class; //Java 
İkinci madde de belirtmiş olduğum nedenden dolayı biz de android'de reflection ile uğraşırken metadatasına ulaşmak istediğimiz bütün nesnelerin enkapsüle edilmesi işlemi esnasında Class nesnesini kullanıyor olacağız. (We are going to use Class object while encapsulating objects on Android because of the reason described section two)
Class x = Object.class;
Constructor[] constructors = x.getDeclaredConstructors();
Field[] fields = x.getDeclaredFields();
Method[] methods = x.getDeclaredMethods();
for (Constructor constructor : constructors) {  
     //constructorlar
} 
for (Field field : fields) {
    //fieldlar 
}
for (Method method : methods) {
    //methodlar
}    

Android CodeBehind'da bir TextView nesnesi yaratırken yaptığımız işlem (Creating a TextView from codebehind on Andriod)
TextView x = new TextView(this); // constructor'a context geçiliyor.

Çalışma zamanında reflection ile yukarıdaki olayın gerçekleştirilmesi: Runtime'da bir TextView nesnesi yaratırken yaptığımız işlem -Constructor'a ulaşmak- (Creating a TextView from codebehind at runtime with using reflection)
String x = TextView.class.toString().replace("class ", "");
Class<?> cls = Class.forName(x);
Class<?> param[] = new Class[1];
param[0] = Context.class; //Context=o an ki context ==> [activity.class]
Constructor<?> ct = cls.getConstructor(param);
Object paramVal[] = new Object[1];
paramVal[0] = context;
Object retobj = ct.newInstance(paramVal); //constructor'a context geçilerek TextView'ın yeni bir instance'ı yaratıldı.
Çalışma zamanında reflection ile yarattığımız TextView nesnesinin setText() methoduna erişiyoruz (Reaching to setText() method at the runtime)
Class methodParam[] = new Class[1];
methodParam[0] = java.lang.CharSequence.class;
Method method = cls.getMethod("setText", methodParam);
Object arglist[] = new Object[1];
arglist[0] = new String("BU TEXTVIEW RUNTIME'DA OLUŞTURULDU");
method.invoke(retobj, arglist); //void method call edildi. 

Bu aşama ve sonrasında yapılacaklar istenen şeye göre elbette değişkenlik arzedecektir, biz burada örnek olması açısından retobj isimli nesnemizi View'a cast ederek ilgili layout'a ekleyeceğiz. (The rest is up to you, I casted retobj to View and added it to a linearLayout as following to set an example)

View v = (View)retobj;
linearLayout.addView(v);

İyi çalışmalar,
(Good work)

26 Ekim 2011 Çarşamba

Failed to allocate memory: 8 This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

[2011-10-26 22:31:49 - Emulator] Failed to allocate memory: 8
[2011-10-26 22:31:49 - Emulator] 
[2011-10-26 22:31:49 - Emulator] This application has requested the Runtime to terminate it in an unusual way.
[2011-10-26 22:31:49 - Emulator] Please contact the application's support team for more information.

Problemi gidermek için
(To resolve the problem)
  1. Eclipse > Window > Avd Manager
  2. Değişiklik yapacağınız virtual device'ı seçin ve Edit'e basın (Select virtual device which you want to edit and click Edit)
  3. Device Ram Size'ı 512 Mb olarak ayarlayın. (Set Device Ram Size as 512 Mb)

This Android SDK requires Android Developer Toolkit version 14.0.0 or above. Current version is 12.0.0.v201106281929-138431. Please update ADT to the latest version.

Sdk 14'ü kurarken aşağıdaki hatayla karşılaşmanız, ADT (Android Development Tools) ve SDK'nızın senkronize olmamasından kaynaklanmaktadır.
(This error happens when there is an incompatibility between ADT and SDK)


Problemi gidermek için
(To resolve the problem)
  1. Eclipse > Help
  2. Install New Software
  3. Work With bölümüne https://dl-ssl.google.com/android/eclipse/ yazıp enter'a basın. (Add https://dl-ssl.google.com/android/eclipse/ to Work With section and press enter) 
  4. Developer Tools'un listede belirdiğini gördükten sonra seçip Next'e tıklayın. (After developer tools appears on the list, check it and click Next)
  5. İşlem bittikten sonra Eclipse'i yeniden başlatın. (Restart eclipse once download finished)

23 Ekim 2011 Pazar

Android ile dataset dönen bir .NET webmethod'unu çağırmak. How to call a .NET webmethod which returns dataset using Android

Arkadaşlar merhaba,
(Hello guys)

10 yılı aşkın bir süredir profesyonel olarak yazılım sektörünün içinde olmam sebebiyle rahatlıkla söyleyebilirim ki gerçek hayat projelerinin neredeyse hiç birinde işler yazılımcının istediği şekilde ilerlemez.  Lafı uzatmadan android'de pek çok kişinin karşılaştığı ancak koca internette "1" tane bile örneğin bulunmadığı bu tür durumlardan birine değineceğim: Android ile .NET'te yazılmış dataset dönen bir webservise erişmek. Aslında hiçbirimiz dataset veya datatable gibi belli bir platforma (.NET) özel oluşturulmuş kompleks bir nesnenin webmethod gibi globallik arz eden bir yapıda dönüş değeri olarak kullanılmasını doğru bulmayacağız, bundan eminim. Fakat sizden böyle bir webmethod'la iletişime geçmenizin istendiğini ve bunun alternatifi olmadığını düşünün, ne yapacaksınız? Bu tamamen yanlış demeniz muhatabınız açısından ne kadar gerçekçi ve kabul edilebilir bir cevap olarak karşılanacak?

(As a professional developer who develops, plans and executes for 10 years, I can conveniently say without any doubt that in real life projects the things rarely comply with our plan. This example is one of them: Today we are going to mention about a case that there can not be found any tutorial on the internet about it, reaching a webservice which returns .NET dataset. I'm sure nobody wants to use these kind of complex objects like dataset or datatable -which runs only in .NET- as a parameter with a webmethod. However let's suppose that you are facing with a case that you need to call a webmethod like this and there is no any alternative way to do. Do they accept it as a reasonable answer when you say this is impossible? Or just think how they react when you say that.)

Gelin nasıl bu işin altından kalkacağımıza bakalım.
(Let's look how do we resolve that.)

Dediğimiz gibi bir webmethodumuz var ve dataset dönüyor. Önceki yazılarımızda 3. parti kütüphane kullanmadan (ksoap2 gibi) android ile bir webservise nasıl soap request atacağımızı ve geri dönüşü nasıl handle edeceğimizi anlatmıştık. Tüm bu bilgiler üzerine dataset dönen bir webmethod'un nasıl bir xml şemasına sahip olduğunu da bilirsek geriye kalan tek şey uygun yapıyı hazırlamak olacaktı ve öyle de oldu. Yeri gelmişken söylemekte fayda var bu tür envelope'un doğru oluşup oluşmadığını deneme amaçlı testlerde soapUI size büyük kolaylık sağlayacaktır.

(As I said there is a webmethod which returns dataset. I mentioned on previous tutorials that we need to know some key facts like how do we send soap request on android without using any third party library like ksoap2 and how do you handle return parameter which comes from AsyncClass on android -at the moment it supports turkish only-. In addition to this, if we know the xml schema of the soap response that comes from a webmethod which returns dataset then we can write the code very easily what we need.)

Bu noktadan sonra şu aşamada olduğumuzu varsayıyorum. (I suppose that we are here at this point)
  1. Soap envelope'umuz hazır,(we prepared the soap envelope)
  2. Webmethod'a başarıyla request attık. (we can call the webmethod without exception)
  3. Response'umuzu XML olarak aldık ve parse edilmeyi bekliyor. (we got the response as xml and it is waiting for parsing)
private DataTable parseAsDataTable(String x, String methodName){  
    //Datatable benim android için geliştirdiğim, .NET'teki DataTable nesnesinin içerdiği neredeyse bütün method ve özellikleri barındıran bir nesne. Siz bunun yerine 2 boyutlu bir object array kullanabilirsiniz. 
    //Datatable is an object that I created for android. It supports a lot of methods and properties of .NET datatable. But you can use 2 dimensional array instead of using this object -Object[row][column]-) 
    DataTable dt = new DataTable(Gonderim.this);
    try {
        String sMethodBaslangic = "<"+methodName+" xmlns=\"\">";
        String sMethodBitis = "";
        int artiBaslangic = sMethodBaslangic.indexOf(">");
        artiBaslangic++;
        int baslangic = x.indexOf(sMethodBaslangic);
        if(baslangic>-1){
            baslangic+=artiBaslangic;
            x = x.substring(baslangic);
            int bitis = x.indexOf(sMethodBitis);
            x = x.substring(0, bitis).replace(":", "_");
            x = new StringBuffer(x).insert(0,"<"+methodName+">").toString();
            x += "";        
            byte[] bytes = x.getBytes();
            ByteArrayInputStream bInputStream = new ByteArrayInputStream(bytes);


            // gelen string'i bir xml haline getiriyoruz.
            // converting string to xml
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            org.w3c.dom.Document doc = docBuilder.parse (bInputStream);
            org.w3c.dom.Element element = doc.getDocumentElement();
            NodeList nl = element.getChildNodes();
            boolean takenColumnNames=false;
            String[] columnArray;
            String columnNames = "";
            int rowIndex =  nl.getLength();
            int colIndex = nl.item(0).getChildNodes().getLength();
            Object[][] dataSource = new Object[rowIndex][colIndex];


            for (int i = 0; i < rowIndex; i++) {
                NodeList nlChildren = nl.item(i).getChildNodes();
                for (int j = 0; j < nlChildren.getLength(); j++) {
                    Node node = nlChildren.item(j);
                    if(!takenColumnNames){
                        columnNames+=node.getNodeName()+",";
                    }
                    dataSource[i][j] = node.getChildNodes().item(0).getNodeValue();
                }
                takenColumnNames = true;
            }


           columnArray = columnNames.split(",");
           dt.setColumns(columnArray);
           dt.setDataSource(dataSource);
        }
    } catch (Exception e) {
        Util.setException(Gonderim.this, e);
    }
    return dt;
    }
Anlaşılmayan bir nokta olursa çekinmeden mesaj atabilirsiniz. İyi çalışmalar.
(Please feel free to contact me if you have any questions)


mgNet Library kullanımı
örnek video



20 Ekim 2011 Perşembe

How to pass a complex object from one activity to another in Android

implement your class with Serializable. Let's suppose that this is your entity class:
import java.io.Serializable;
@SuppressWarnings("serial") //with this annotation we are going to hide compiler warning
public class Deneme implements Serializable {
public Deneme(double id, String name){
    this.id = id;
    this.name = name;
}
public double getId() {
    return id;
}
public void setId(double id) {
    this.id = id;
}
public String getName() {
    return this.name;
}
public void setName(String name) {
    this.name = name;
}
private double id;
private String name;
}
we are sending the object called dene from X activity to Y activity. Somewhere in X activity;
Deneme dene = new Deneme(4,"Mustafa");
Intent i = new Intent(this, Y.class);
i.putExtra("sampleObject", dene);
startActivity(i);
In Y activity we are getting the object.
Intent i = getIntent();
Deneme dene = (Deneme)i.getSerializableExtra("sampleObject");
that's it.