Android ilk çıktığı zamanlarda baştan başlayarak bir makale dizisi yazmayı hayal etmiştim. Ancak zamansızlıktan yalan oldu. Şimdi ise iş arkadaşlarımın yemek seçme kararlarını beklerken hızlıca ufak bir makale yazayım dedim.
Bir programcı için yazdığı uygulamanın kitlenmesi neredeyse bir kara leke gibi birşeydir herhalde. Hemen damgalanır. Son kullanıcı durmandan oraya buraya basar uygulama da her aksiyonu işlemek zorunda olduğu ve işlemci gücü yetmediğinden kitlenir. Gayet doğal bir sonuç ama çözümü elbette var! Kullanıcıyı gereksiz aksiyondan uzak tutmak. Yani bir işlem yaparkan Progress Dialog çıkartmak gerek en basitinden. Kullanıcıyı işlem hakkında bilgilendirmek gerek.
Bazı işlemler de var ki uzun sürer ama o süre boyunca kullanıcıyı boşuna bekletmek yersiz. Arkaplanda kullanıcının ruhu duymadan işlemi yapmak için “Asenkron İşler” yardımımıza koşar. Anlatacağım işlemler her dilde hemen hemen aynıdır yani en azından mantık bakımından. Hadi yapalım bakalım.
Örneğin, uygulama açılırken kullanıcıyı bekletmeden arka planda versiyon kontrol edelim. Uygulamamızın yeni sürümü çıkmışsa kullanıcıyı bilgilendirelim.
onStart eventinde checkUpdate metodunu çağıralım. Metodun içeriğini inceleyelim.
private void checkUpdate() {
// Kullanici bir onceki ekrandan tekrar buraya geldiyse tekrar tekrar calismamasi icin bir kontrol
if (isUpdateChecked)
return;
// Islemi bir thread altinda yapiyor olacagiz.
// Thread de bir Runnable nesnesinin icerisindeki run metodunu cagiracaktir.
// Biz de o run metodunun icerigini dolduracagiz.
Thread th = new Thread(new Runnable() {
@Override
public void run() {
// Serverdan guncel versiyonun bilgileri cekilip nesneye donusturulmus hali. CustomPackageInfo diye bir class.
CustomPackageInfo cpi = GetLatestVersionInformation();
try {
if (cpi != null) {
PackageInfo pi; // suan telefonda yuklu olan uygulamamizin versiyon bilgileri
pi = getPackageManager().getPackageInfo(
getPackageName(), 0);
if (cpi.VersionCode > pi.versionCode
&& !cpi.VersionName.equals(pi.versionName)) {
{
// Guncelleme icin kullanilacak activity ekrani (UpdateActivity.class) 'nin sabit degiskenleri
UpdateActivity.WhatsNew = cpi.WhatsNew;
UpdateActivity.GoToURL = cpi.Url;
// Sabit degiskenler yerine bundle ile de parametreleri gonderebilirsiniz.
// Kullaniciyi bilgilendirme amacli uyari sistemini kullanalim
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.logo;
CharSequence tickerText = "Uygulamimizin yeni bir sürümü mevcut! Lütfen yükleyiniz!";
long when = System.currentTimeMillis();
Notification notification = new Notification(
icon, tickerText, when);
notification.defaults |= Notification.DEFAULT_SOUND;
Context context = getApplicationContext();
CharSequence contentTitle = "Güncelleme bulundu!";
CharSequence contentText = "Uygulamamizin yeni sürümünü yükleyiniz!";
// Uyari sisteminden bizim uyariya tiklaninca hangi intentin yani hangi activity - ya da ekran da diyebilirsiniz - inin calisacagini belirtiyoruz.
Intent notificationIntent = new Intent(
getApplicationContext(),
UpdateActivity.class); // UpdateActivity.class bizim guncelleme hakkinda bilgi verdigimiz ekran
// Uyari sisteminde bekleyen uyarilarilara bizim uyariyi ekliyoruz.
PendingIntent contentIntent = PendingIntent
.getActivity(
getApplicationContext(), 0,
notificationIntent, 0);
// Uyari sisteminde bizim uyarinin en son uyari oldugunu belirtiyoruz.
notification.setLatestEventInfo(context,
contentTitle, contentText,
contentIntent);
// Ve son olarak uyari sistemine uyarimizi gonderiyoruz. Geri kullanici ile telefonu arasinda.
mNotificationManager
.notify(0, notification);
}
}
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
isUpdateChecked = true;
});
th.start(); // ve son olarak bu asenkron islemi baslatiyoruz. Start dedikten sonra run metodunu icerigi calisacaktir.
}
Aslında yukarda böyle bir kod yazmayı düşünmemiştim. Ama olsun. Arada Android’te Uyarı Merkezini (Notification Manager) incelemiş olduk.
Kısacası yapmak istediğimiz işleri Thread altında yapıyoruz. Keşke bu kadar kolay olsa herşey. Aslında direk olarak herhangi UI birimine (bir edittext’e vs) çalışma anında erişmiyorsak sorun olmaz. Peki erişmek istersek o zaman ne yaparız? UI güncellemeleri için sisteme bir mesaj göndeririz. Sırası geldiğinde UI’i güncelleyecektir. Birçok yolu mevcut aslında. Hadi birini yapalım.
onCreate metodunda istediğimiz gibi UI’i değiştirelim sorunsuz bir şekilde günceleyecektir. Ancak content tamamen yüklendikten sonra UI’e eriştiğimizde thread hatasıyla karşılaşabiliriz. Bu tür süpriz durumların olmaması için şöyle yapıyoruz.
Diyelim ki bir butona basınca serverdan data çekip, sonra da o datayı UI birimlerine bind edeceğiz. Bu süre boyunca kullanıcıya bir Progress Dialog çıkartmakta yarar var.
Runnable dataRunnable = new Runnable() {
@Override
public void run() {
getData();
}
};
Thread th = new Thread(null, dataRunnable, "backgroundJob");
th.start();
// mProgressDialog değişkenimiz bir field ki başka yerden erişmemiz gerekecek
// ki işlemimiz bitince progress dialogu kapatacağız.
// Progress Dialog'u çıkartıyoruz.
mProgressDialog = ProgressDialog
.show(this, "Lütfen Bekleyiniz...","Data getiriliyor... ");
/*
getData metodunda datayı çektikten sonra UI ile ilgi bir güncellememiz olduğunu bildirmemiz gerekecek.
*/
private void getData(){
mErrorMessage = "";
try {
// Serverdan datamizi cekiyoruz.
mResult = new DataManager().getNewData();
// isimlere takilmayin suan tamamen salliyorum. :)
} catch (Exception e) {
mErrorMessage = "Bir hata oluştu! " + e.getMessage();
} finally {
// en onemli kisim: her durumda islemi sonlandirip kullaniciyi bilgilendirmemiz gerekecek.
// iste UI ile ilgili bir islem yapacagimizi bildirdigimiz yer burasi
runOnUiThread(mReturnResultRunnable); // mReturnResultRunnable UI ile ilgili islemlerimizi yapacagiz. Private bir field
}
}
private Runnable mReturnResultRunnable = new Runnable() {
@Override
public void run() {
// Herhangi bir hata olusup olusmadigini kontrol ediyoruz. Datamizi dogruluyoruz.
// Burda datamizi UI birimlerine bind ediyoruz.
// Ornegin: mResult bir Collection ise ve biz de bu datayi ListView'da gosteriyorsa bu islemi burda yapacagiz.
mProgressDialog.dismiss(); // islem bitti. Progress Dialog'umuzu kapatiyoruz.
}
};
private String mErrorMessage;
İşte en basit anlamda en çok ihtiyaç duyulan bu konuda işler böyle yapılabilir.
Başka bir zaman ne yazarım bilmiyorum gerçekten
Görüşmek üzere
İyi kodlamalar













