UYARI: Bu bölümde anlatılan projeler Google tarafından resmen desteklenmemektedir ve Android SDK ile birlikte sunulmazlar. Söz konusu projeler çeşitli geliştiricilerin kendi ihtiyaçları için yazdığı ve açık kaynak haline getirip herkesin kullanımına sunduğu kodlar içerir. Bu kodları kendi projelerinizde kullanmak sizin sorumluluğunuzdadır. Oluşabilecek bellek hataları ya da uygulamanın çökmesi gibi durumları Google Play'e göndermeden test etmenizi tavsiye ederiz.
ImageLoader
Eğer bir ImageView içerisindeki resim İnternet üzerindeki bir kaynaktan yüklenecekse bu resmin asenkron bir bağlantı açılarak ana akışı bozmadan yüklenmesi tavsiye edilir. Özellikle ListView gibi satırları sürekli güncellenen yapılarda resimlerin yüklenmesi uygulamanın takıldığı hissine yol açmamalı ve aynı resim için tekrar tekrar bağlantı açılarak İnternet paketi ve pil gereksiz tüketilmemelidir. Bu yüzden resimlerin AsyncTask gibi yapılarla asenkron yüklenmesinin yanı sıra yerel bir hafızada tutulması (cache) de gerekir.
ImageLoader projesi Android uygulamaları için resimlerin uzak kaynaklardan sorunsuz yüklenmesi ve yerelde saklanması işlemlerini üstlenir. ListView satırları içinde yer alan ImageView görselleri ile de kullanılabilen ImageLoader, cihaz hafızasında ya da SD kart üzerinde resimleri saklayarak tekrar yüklemelerin de önüne geçer.
Kod içerisinde ImageLoader’ı kullanmak için statik getInstance metodunu çağırmamız yeterlidir;
ImageLoader imageLoader = ImageLoader.getInstance();
Bundan sonra yapılması gereken hangi resmin hangi ImageView içerisine yüklenmesi gerektiğini söylemek olacaktır;
ImageLoader imageLoader = ImageLoader.getInstance();
ImageView imageView = (ImageView)rowView.findViewById(R.id.rss_image);
String imageUrl = object.getImageUrl();
imageLoader.displayImage(imageUrl, imageView);
ImageLoader yüklendikten sonra resmin gösterilmesini istediğimiz ImageView öğesini findViewById metoduyla buluyoruz. Ardından resmin İnternet adresini (URL) alıyoruz ve displayImage metoduyla ImageLoader'ın resmi asenkron yüklemesini sağlıyoruz. Bu şekilde resim ana akışı bloke etmeden yüklenecek ve sonrasında ekrana gelecektir.
ImageLoader projesi Android 2.0 ve üzeri sürümleri desteklemektedir.
Proje adresi: https://github.com/nostra13/Android-Universal-Image-Loader
Spring for Android
Dünyaca ünlü Spring Framework’ün Android geliştiricilere yönelik birtakım özelliklerinin toplandığı Spring for Android, uzaktaki bir sunucuda yer alan bir JSON kaynağı (REST API) kolaylıkla objeye dönüştürmenizi ve kullanmanızı sağlar. İçinde barındırdığı HTTP kütüphaneleri ve JSON çeviriciler ile herhangi bir REST API üzerinden elde ettiğiniz cevabı dilediğiniz sınıfa modelleyebilirsiniz. Öncelikle aşağıdaki REST servise göz atalım;
[{"name" : "Grand Canyon", "lat" : 36.195525, "lon" :
-112.631836},{"name" : "London Eye", "lat" : 51.503267,
"lon" : -0.120850},
{"name" : "Eiffel Tower", "lat" : 48.857769, "lon" :
2.293439},
{"name" : "Bosphorus", "lat" : 41, "lon" : 29},
{"name" : "Selimiye Camii", "lat" : 41.678105, "lon" :
26.558568},
{"name" : "Kremlin", "lat" : 55.751656, "lon" : 37.616844}]
Yukarıdaki örnekte gördüğümüz gibi her mekâna ait name, lat ve lon özellikleri bize JSON içinde döndürülüyor. Bu objeleri bir Java sınıfına aşağıdaki gibi modelleyelim;
package com.turkcell.poisearch.model;
import org.codehaus.jackson.annotate.JsonProperty;
public class Poi {
private String name;
@JsonProperty("lat")
private Double latitude;
@JsonProperty("lon")
private Double longitude;
@Override
public String toString() {
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
}
Poi sınıfında JSON içinde gelen özellikle sırasıyla name, latitude ve longitude özelliklerine atanacaktır. JSON içerisindeki lat değeri Java sınıfındaki latitude değerine atanacağından bu durumu JsonProperty anotasyonu ile belirtiriz. Bu sayede Spring otomatik modelleme yaparken değişken isimlerini şaşırmayacaktır. toString metodu ise Activity içerisinde ArrayAdapter kullanılması için kolaylık sağlamaktadır. Son olarak da Activity içerisinde HTTP isteği yapan ve cevabı objeye modelleyen kodu inceleyelim;
private class PoiDownloadTask extends AsyncTask<Void, Void,
ResponseEntity<Poi[]>> {
@Override
protected ResponseEntity<Poi[]> doInBackground(Void... params) {
String url = "http://bilmiyordum.com/poi.json";
HttpHeaders requestHeaders = new HttpHeaders();
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new
MappingJacksonHttpMessageConverter());
ResponseEntity<Poi[]> response = restTemplate.exchange(url,
HttpMethod.GET,
new
HttpEntity<Object>(requestHeaders),
Poi[].class);
return response;
}
@Override
protected void onPostExecute(ResponseEntity<Poi[]> result) {
ArrayAdapter arrayAdapter = new
ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1,
result.getBody());
poiListView.setAdapter(arrayAdapter);
super.onPostExecute(result);
}
}
Web servisten gelecek cevabın bir Poi dizisi olduğunu bildiğimizden doInBackground metodunun cevabını ResponseEntity<Poi[]> olarak belirliyoruz. Bu da bize gelen cevabın bir Poi dizisine modellenceğini bildiriyor. RestTemplate sınıfı ise gerekli değişkenlerle bir http isteği gerçekleştirmemizi sağlıyor. exchange metodu çalıştıktan sonra istek gerçekleşiyor ve cevap Poi[].class (Poi dizisi) şeklinde bize döndürülüyor. Biz de bu cevabı onPostExecute metodu içerisinde bir ArrayAdapter'a gönderiyoruz ve ekranda mekânları dolduruyoruz.
Yapılan örnek projeye ait tüm kodları sol yukarıdaki bağlantıdan indirebilirsiniz. Spring for Android projesinin güncel sürümünü ise aşağıdaki bağlantıdan temin edebilirsiniz.
Projenin adresi: http://projects.spring.io/spring-android/