Mobil Programlama

Android

Düzenli Güncellemelerin Etkilerini Azaltmak

Lisans: Creative Commons 26.11.2020 tarihinde güncellendi
Bakabileceğiniz Etiketler: Eğitmen: Geleceği Yazanlar Ekibi

Uygulamanızın düzenli güncelleme ihtiyaçları için en uygun sıklık; cihazın durumuna, ağ bağlantısına, kullanıcı alışkanlıklarına ve tercihlerine bağlı olarak değişecektir.

Daha önceki eğitimlerde, yenileme sıklığını cihazın durumuna göre değiştiren pil dostu uygulamaların nasıl yazılacağından bahsetmiştik. Bağlantı gittiğinde arkaplan uygulamaların güncellemelerini devre dışı bırakmak ve pil düşük seviyedeyken güncellemelerin sıklığını azaltmak yöntemlerden ikisiydi.

Bu eğitim içeriğinde, arkaplan uygulamalarının yenileme sıklığının, kablosuz bağlantı anteni durum makinesine (wireless radio state machine) etkisini en iyi nasıl azaltacağınızı inceleyeceğiz.

 

Sürekli yoklamak yerine Google Cloud Messaging'i kullanmak

Uygulamanız güncellemeye ihtiyaç var mı diye her seferinde sunucuyu yoklarken kablosuz bağlantı antenini aktif hale getirir ve gereksiz yere normal bir 3G bağlantısındaki yaklaşık 20 saniyelik sürede gereken kadar güç çeker. Doğrusu, bunu hiç kimse istemez.

Android için Google Cloud Messaging (GCM) mekanizması, sunucudan uygulamanın herhangi bir kısmına veri transfer etmenin kolay yollarından biridir. Transfer edilecek yeni veri geldiğinde, sunucunuz Google Cloud Messaging'i kullanarak, herhangi bir cihazda o an çalışan uygulamanıza bilgi verebilir.

GCM'nin bu olay güdümlü yöntemini, uygulama içinde sürekli yeni veri olup olmadığını kontrol etmek için sunucuyu kontrol etme (buna yer yer sürekli yoklama yöntemi diyeceğiz) yöntemiyle karşılaştırınca, GCM'li yöntemin sadece indirilecek yeni veri olduğunda yeni bağlantı oluşturmasını sağladığını görebilirsiniz. Bu gayet mantıklı bir çözüm.

Sonuç olarak, GCM kullanırsanız gereksiz bağlantıları azaltmış olursunuz ve uygulamanızda güncellenecek verinin geç güncellenmesinin önüne geçersiniz.

GCM, kalıcı (persistent) TCP/IP bağlantısı kullanarak oluşturulmuştur. Kendi bildirim sisteminizi kuracaksanız en iyi yöntem GCM'dir. GCM, kalıcı (persistent) bağlantılarınızın sayısını mümkün olan en az seviyeye indirir ve bant genişliğini en uygun biçimde kullanarak batarya kullanımı üzerindeki etkiyi azaltır.

 

Kesinlik içermeyen (Inexact) tekrarlı uyarılar ve üstel geri çekilme (Exponential Backoff) yöntemleri

Yeni veri denetimi için sunucuyu yoklamak zorundaysanız, bu yoklama sıklığını kullanıcı deneyiminden feragat etmeyecek kadar düşük tutmalısınız. Bir başka deyişle, ne kadar az o kadar iyi.

En güzel yaklaşım, kullanıcıya güncelleme sıklığını ayarlama fırsatı vermektir. Böylece güncellik ve cihaz pili ömrü dengesini kurmayı kullanıcıya bırakırsınız.

Güncelleme işlemlerinizi zamanlayacağınız zaman, kesinlik içermeyen (inexact) uyarıları kullanmalısınız.

int alarmType = AlarmManager.ELAPSED_REALTIME;
long interval = AlarmManager.INTERVAL_HOUR;
long start = System.currentTimeMillis() + interval;

alarmManager.setInexactRepeating(alarmType, start, interval, pi);

Çeşitli uyarılar, benzer zamanlarda çalışmak için ayarlandıysa, Android'in bu zaman kaydırma özelliği onların eşzamanlı olarak tetiklenmesine neden olacaktır. Bunun güzel yanı da her güncellemenin tek bir aktif radyo anteni durumunda gerçekleşmesini sağlamasıdır.

Mümkünse uyarınızı _WAKEUP içeren yani cihazı uyandıran uyarılar yerine ELAPSED_REALTIME veya RTC tipli uyarılar haline getirin. Bu değişiklik, uyarının devreye girmesi için telefonun uyku modundan çıkana kadar beklemesini sağlayarak cihaz pili ömrünü uzatır.

İleride, uygulamanızın kullanım durumuna göre bu zamanlanmış uyarıların sıklıklarını düşürerek etkilerini azaltabilirsiniz.

Uygulamanız son veri güncellemesinden beri kullanılmamışsa, güncelleme sıklığını (ve/veya sağladığınız önceden indirmenin (prefetch) derecesini) azaltacak üstel geri çekilme (exponential backoff) yöntemi oluşturabilirsiniz. Genellikle güncelleme zamanını uygulamanın kullanılma zamanına göre düşürmek faydalıdır. Örneğin;

SharedPreferences sp = 
  context.getSharedPreferences(PREFS, Context.MODE_WORLD_READABLE);

boolean appUsed = sp.getBoolean(PREFS_APPUSED, false);
long updateInterval = sp.getLong(PREFS_INTERVAL, DEFAULT_REFRESH_INTERVAL);

if (!appUsed)
  if ((updateInterval *= 2) > MAX_REFRESH_INTERVAL)  
    updateInterval = MAX_REFRESH_INTERVAL;

Editor spEdit = sp.edit();
spEdit.putBoolean(PREFS_APPUSED, false);
spEdit.putLong(PREFS_INTERVAL, updateInterval);
spEdit.apply();

rescheduleUpdates(updateInterval);
executeUpdateOrPrefetch();

Buna benzer bir üstel geri çekilme kalıbını da başarısız bağlantıların ve indirme hatalarının etkilerini azaltmak için kullanabilirsiniz.

Bir ağ bağlantısı kurmanın bedeli, veri indirseniz de indirmeseniz de sunucunuza bağlanmakla aynıdır. Başarılı olması önemli olan zaman odaklı aktarmalarda tekrar deneme sıklığını azaltmak için üstel geri çekilme kalıbı kullanılabilir. Pil ömrüne olan etkiyi azaltacaktır. Örneğin;

private void retryIn(long interval) {
  boolean success = attemptTransfer();
    
  if (!success) {
    retryIn(interval*2 < MAX_RETRY_INTERVAL ? 
            interval*2 : MAX_RETRY_INTERVAL);      
  }
}

Başka bir yol olarak, düzenli güncellemeler gibi hata toleransı olabilecek aktarımlarda, başarısız bağlantıları ve denemeleri yoksayabilirsiniz.

Bu sayfadaki metinler Android Open Source Project kapsamında oluşturulmuş ve paylaşılmış içeriğin küçük değişiklikler yapılmış hâlidir ve Creative Commons 2.5 Attribution License'ta belirlenen koşullara göre kullanılmıştır.

Bu eğitim içeriğinin orijinal hâline buradan ulaşabilirsiniz: Minimizing the Effect of Regular Updates