Android Context Nedir ?

Merhaba,

Bugün Android’e uygulama yazarken sıkça kullandığımız bir sınıf olan Context’ten (android.content.Context)  bahsedeceğim. Activity başlatmak, broadcast atmak, view güncellemek, shared prefe erişmek için her zaman context’e ihtiyaç duyarız. Peki nedir bu context? Her context aynı mıdır? Şimdi bu soruların cevabını arayalım.

 

Nedir Bu Her Yerde Kullandığımız Context ?

Kabaca context,

Android sistemi tarafından soyut bir şekilde bize sunulan, uygulamamız hakkında global bilgiye sahip arayüzdür. Bir nevi uygulamamızın komponentlerinin kimliğidir diyebiliriz. Uygulama sistem veya yerel bazda kaynaklara erişmek istediğinde bu kimliği kullanır işletim sistemi de bu kimliğin yeterliliğine göre işlemi başlatır.

Context sayesinde işletim sisteminin bize sunduğu  uygulama özelindeki servislere erişebilir (Wifi Service, Activity Service, Location Service gibi) yine aynı şekilde uygulama seviyesinde operasyonları (activity başlatma, intent gönderme/alma gibi. ) gerçekleştirebiliriz.

Context’e birden fazla şekilde erişebiliriz. Şimdi bu erişim yollarını ve birbirinden farklarını inceleyelim.

Context Tipleri

Application Context (getApplicationContext()) – Uygulama prosesinde çalışan single instance’tır. Uygulamanız yaşadığı sürece yaşamına devam .eder. Farklı yerlerden erişim sağlasanız da aynı instance’ı elde edersiniz. Activity veya Service üzerinden getApplication() apisini çağırarak veya Context’i miras alan herhangi bir sınıftan getApplicationContext() apisini çağırarak erişebilirsiniz.

Activity/Service – ContextWrapper’dan türer ve her activity/service context kendine özgüdür. Activity yaşam döngüsüne bağlıdır. Activity’nin kendisi this contexti içerir. Bunun dışında MyActivity.this şeklinde de context’e ulaşabilirsiniz.

BroadcastReceiver – Kendisi context’e sahip değildir, broadcast için android yeni bir context oluşturmaz ancak onReceive() metodu içerisinden context sistem tarafından sağlanır. Buradaki context ReceiverRestrictedContext  instance’ıdır ve iki temel fonksiyonu kapalıdır. Bunlar:

  • Herhangi bir broadcast receiver içerisinden başka bir receiver’a kayıt (registerReceiver()) olamazsınız.
  • Bir service’e bind (bindService()) olamazsınız.

Broadcast receiver içerisinde onReceive() tetiklenmesi sonucunda gelen her context’in instance’ı birbirinden farklıdır.

ContentProvider – İçerisinde context barındırmaz. Ancak oluşturulduğunda bir context atanır. Atanan context uygulama contextidir. Eğer context provider uygulama içi veya aynı proses içerisinde çalışıyorsa sağlanan contextler aynı olur. Eğer ayrı prosesler ise temsil edilen her packet için ayrı context olur.

Herkesin Context’i Kendine

Farklı context türlerinden bahsettik.Şimdi bu context’lerin neleri yapıp yapamayacağından bahsedelim. Aşağıdaki tabloda hangi türdeki contextlerin neleri yapabileceğini görebiliriz.

getApplicationContext()’i Nerelerde Kullanmalıyız?

getApplicationContext() daha önce bahsettiğimiz gibi uygulamaya özel single instance bir context döndürür. Application komponenti, uygulamamızın global durumunu tutar.

Application context kullanmadan önce kendimize şu soruları sormalıyız?

  • Contexti uzun süre kullanan başka bir sınıfımız var mı? Eğer böyle bir sınıfımız varsa Activity context’i vermek memory leak’e sebep olabilir. Eğer işleminiz uzun süreli ve context’e ihtiyacınız varsa Application Context’i kullanmalıyız.
  • Uygulamanın görseli ile ilgili bir değişiklik yapıyor muyum?Arayüzde yaptığımız değişikliklere ait tema bilgileri Application Context’te bulunmaz. Bu da sorunlara yol açabilir. Uygulamanızın farklı activitylerinde farklı temalar kullanabilirsiniz. Özet olarak arayüz ile ilgili işlem yapıyorsak, o arayüze bağlı activity’nin contextini kullanmalıyız.

Activity Context’ini Nerelerde Kullanmalıyız ?

Activity’den oluşturulan context , activity yaşam döngüsü boyunca yaşar. Bundan dolayı activity contextini sadece o activity ile ilgili gerekli işlemlerde kullanmalıyız.

Context ile ASLA Yapmamamız Gereken Şeyler

Android her komponente uygun olacak context’i belirlemiştir. Context’i komponentler arası parametre olarak geçirmemeliyiz. Broadcast receiver ile gelen context’i activity’de, activity context’ini servis içinde kullanmamalıyız.

Memory leak oluşmaması için asla static Context değişkeni tutmamalıyız.

Eğer bunlardan birisini yaptıysak yazdığımız kodu tekrar gözden geçirmemiz faydalı olacaktır.

Eğer hangi context’i kullanmanız konusunda emin olamıyorsanız Application Context’i kullanın 🙂

 

Kaynaklar:

İyi kodlamalar,

 

Loading

Facebooktwitterredditpinterestlinkedinmail

Geçici veya Kalıcı Olarak Linux’ta Bilgisayar Adını (Hostname) Değiştirme

Merhaba arkadaşlar,

Bu yazımda linux makinanızın bilgisayar adını geçici ve kalıcı olarak değiştirmeden bahsedeceğim.

Geçici olarak bilgisayar adı (hostname) değiştirme:

sudo hostname "BilgisayariminYeniAdi"

Bu kadar basit. 🙂 Yalnız buradaki değişikliğin bilgisayarınızın yeniden başlatılana kadar geçerli olacağını unutmayın.

Kalıcı olarak bilgisayar adı (hostname) değiştirme:

bilgisayar adını kalıcı olarak değiştirme için iki yerde değişiklik yapmamız gerekiyor. Bu yerler:

  • /etc/hosts
  • /etc/hostname

 

sudo vim /etc/hostname

hostname dosyası

Son olarak /etc/hosts dosyamızı da değiştirelim. Burada iki dosyaya da aynı ismi vermeyi unutmayın. Yoksa “unable to resolve host” hatasıyla karşılaşabilirsiniz.

sudo vim /etc/hosts

hosts dosyası içeriği

Favori text editörünüzle yukarıdaki yerleri açarak istediğiniz adı girip kaydedin. PC’nizi yeniden başlattığınızda bilgisayar adınız değişmiş olacaktır.

 

İyi çalışmalar,

Loading

Facebooktwitterredditpinterestlinkedinmail

XIAOMI 90 ULTRA FUN KOŞU AYAKKABISI CİHAZ EKLEME PROBLEMİ

Merhaba arkadaşlar,

 

Yakın zamanda hepsiburada.com üzerinden Xiaomi 90 Ultra Fun koşu ayakkabısı aldım. Google Play üzerinden Xiaomi Home uygulamasını indirdim. Üyelik oluşturdum. Ancak cihazı bir türlü ekleyemedim. Eğer siz de bu sorunla karşılaştıysanız buyrun çözüm aşağıda:

 

  1. https://play.google.com/store/apps/details?id=com.xiaomi.smarthome adresinden uygulamayı indirelim.
  2. Üyeliğimiz varsa giriş yapalım. Yoksa yeni üyelik oluşturalım.
  3.  Hesabımızı onaylayıp giriş yaptıktan cihaz ekleme’ye basalım.  Bu kısım önemli – açılan ekranda 90 urevo listelenmiyorsa yanlış serverdasınız demektir.  Şimdi server ayarlarımızı değiştirelim.
  4.  Sağ alt kısımdan Profile’a tıklayalım. Settings’e gelerek Locale kısmını “The United States (Singapore Server)” olarak değiştirelim.

  5. Bu işlemi yaptıktan sonra yeniden giriş yapmanız gerekecek.
  6. Giriş yaptıktan sonra cihaz ekleme kısmına gelelim.  Cihazlar listesinde 90 Urevo’nun listelendiğini göreceksiniz.
  7. Ekrandaki eşleştirme adımlarını takip ederek cihazımızı ekleyelim.

Ben server değiştirmeyi bulana kadar baya uğraştım. Siz uğraşmayın 🙂

Bu arada çipi şarj ettikten sonra sağ ayakkabının tabanını çıkartarak kolayca yerleştirebilirsiniz.

 

 

İyi koşular,

 

 

Loading

Facebooktwitterredditpinterestlinkedinmail

SINGLETON PATTERN NEDİR? NERELERDE KULLANILIR?

Merhaba,

Bugün en yaygın tasarım patternlerinden olan Singleton Pattern’inden bahsedeceğim.  Singleton yazılım patterni  Creational Design Patterns(Yaratıcı Tasarım Kalıpları) kategorisinde yer alır. Oluşturulan sınıfın sadece bir adet instance’ı olmasını garantiler. Tanımı kolay olmasına rağmen konu implementasyona gelince bir çok yöntem bulunmaktadır ve her zaman yazılımcılar arasında hangi yöntemin kullanılması gerektiği tartışmalı bir konudur. Burada singleton tasarım patterninin ilkelerinin neler olduğunu ve bu modeli uygulamak için kullanılan yöntemleri teker teker inceleyeceğiz.

Singleton tasarım patternine tüm örnek Java kodlarını aşağıdaki github reposunda bulabilirsiniz:

Singleton Pattern Örnek Java

Java Singleton Pattern İlkeleri

  • Singleton pattern bir sınıftan birden fazla instance oluşmasını engeller ve sanal makinada oluşturulan tek instance’ın kullanılmasını garanti eder.
  • Singleton sınıfı, sınıfa ait instance’a ulaşmak için global erişim sağlamalıdır.
  • Singleton sınıfının constructor’ı private olmalıdır. Böylece o sınınftan yeni instance oluşturmak engellenmiş olur.
  • Singleton sınıfın instance’ı içeride private static olarak tutulmalıdır.
  • Tutulan instance’ı döndüren bir public static metoda sahip olmalıdır.

Daha önce bahsettiğim gibi bu pattern birden çok şekilde gerçeklenebilir. Bu yöntemler aşağıdaki gibidir:

  1. Sabırsız Gerçekleme (Eager Initialization)
  2. Statik Blok Yöntemi (Static Block Initialization)
  3. Tembel Gerçekleme (Lazy Initialization)
  4.  Thread Safe Gerçekleme (Thread Safe Initialization)
  5. Bill Pugh Singleton Yöntemi (Bill Pugh Singleton Implementation)

1.Sabırsız Gerçekleme (Eager Initialization)

Bu yöntemde sınıfın instance’ı sınıfın yüklenme anında oluşur. Singleton patterninin en kolay implementasyonlarından biridir. Ancak instance, sınıfın yükleme anında oluştuğundan sınıf kullanılmasa bile instance oluşacağından gereksiz yer kaplar.

Bu yöntemle aşağıdaki gibi singleton patternini oluşturabiliriz:

package codegenius;

/**
 *
 * @author codegeni.us
 */
public class EagerInitialization {
    
    // define private instance.
    private static final EagerInitialization instance = new EagerInitialization();
    
    //Restrict to create new instance.
    private EagerInitialization(){
    }
    
    // use only created instance via public method.
    public static EagerInitialization getInstance(){
        return instance;
    }
}

Eğer oluşturğunuz sınıf çok fazla kaynak tarafından kullanılmıyorsa bu yöntemi kullanabilirsiniz. Ancak genelde singleton sınıfları dosya sistemlerine erişim, loglama, veritabanı bağlantıları vs, kullanıldığı için sınıf çağrılmadan instance’ı oluşturmaktan kaçınmalıyız. Yukarıdaki yöntemde oluşacak bir exception’ı da ele almak imkansızdır.

2. Statik Blok Yöntemi (Static Block Initialization)

Statik blok yöntemi de aynı şekilde Eager yönteme benzer ancak aradaki fark oluşacak exceptionları ele alabiliriz. Yine sınıfın instance’ı sınıfın yüklenme anında oluşur. Ve bu az öncede söylediğimiz gibi çokta istediğimiz bir şey değil.

Örnek kod aşağıdaki gibidir:

package codegenius;

/**
 *
 * @author codegeni.us
 */
public class StaticBlock {
    
    // define private static instance
    private static StaticBlock instance;
    
    // avoid create instance of class
    private StaticBlock(){}
    
    //static block that supports exception handling
    static{
        try{
            instance = new StaticBlock();
        }catch(Exception e){
            // exception occured handle me.
            throw new RuntimeException("Exceptions can be handled here." + e );
        }
    }
    
    // global accessor method for instance.
    public static StaticBlock getInstance(){
        return instance;
    }
}

 

3. Tembel Gerçekleme (Lazy Initialization)

Bu yöntem sınıfın instance’ı o sınıfa erişmek istenildiği anda oluşturulur. Eğer bu sınıfa birden fazla thread erişmiyorsa sorunsuz olarak çalışır. Birden fazla thread instance’ın oluşturulduğu yere aynı anda girerse farklı instance lar oluşur bu da singleton ilkesine aykırıdır. Farklı threadler olmadığı zaman bu yöntemde instance sınıfın yüklenme anında değil çağırılma anında oluştuğu için faydalıdır.

Örnek kod aşağıdaki gibidir:

package codegenius;

/**
 *
 * @author codegeni.us
 */
public class LazyInitialization {
    
    // define private instance but don't create it.
    private static LazyInitialization instance;
    
    // avoid to create new instance of class
    private LazyInitialization(){}
    
    // global accessor for instance.
    public static LazyInitialization getInstance(){
        
        /** !!! be aware. This is not thread safe.If two or more threads try to
         * access and creates the instance of the class at the same time.
         * That time the Singleton pattern will be destroyed. */
        if(instance == null){
            instance = new LazyInitialization();
        }
        return instance;
    }
}

Bu yöntemi kullanırken  birden fazla thread aynı anda ulaşırsa sorun olacağından bahsetmiştik. Aşağıdaki resimde iki thread singleton instance’ı oluşturuyor ve instance lar birbirinden farklı.

 

Lazy initialization failure.

 

4. Thread Safe Singleton

Az önceki örneğimizde sınıf instance’ı, sınıfın çağırılma anında oluşturularak implement edilen singleton patterninin nasıl thread safe olmadığını kanıtlamıştık. Şimdi lazy initialization yöntemini nasıl thread safe yapabileceğimize göz atalım.

Bunun en kolay yolu sınıfın global erişim metoduna synchronized koymaktır. Böylece metod herhangi bir thread tarafından çağırıldığı anda diğer threadler bu sınıfa erişemez ve birden fazla instance oluşturmanın önüne geçilmiş olur.

Örnek Java kodu:

package codegenius;

/**
 *
 * @author codegeni.us
 */
public class ThreadSafeSyncronized {
    
    // define private instance
    private static ThreadSafeSyncronized instance;
    
    // avoid create instance of class from outside
    
    private ThreadSafeSyncronized(){}
    
    /** syncronize class method for avoid multiple access */
    public synchronized static ThreadSafeSyncronized getInstance(){
        
        if(instance == null){
            instance = new ThreadSafeSyncronized();
        }
        return instance;
    }
    
    public void sampleMethodA(){
        //do awesome stuff here.
    }
    
    public void sampleMethodB(){
        // do awesome things here.
    }
}

 

Yukarıdaki metodta birden fazla erişim engellenir ancak synchronized kelimesi sınıfın tamamını kitlediği için performans sorunu yaratır. Örneğin aşağıdaki gibi bir kullanımda sampleMethodA() ve sampleMethodB() fonksiyonları farklı metodlar olmasına rağmen farklı threadler tarafından aynı anda çağırılamaz. Çünkü getInstance’a koyduğumuz synchronized anahtar kelimesi tüm sınıfı kitler ve tek threadin kullanımına sunar. Bu da singleton yapısının bozulmamasını garantiler ancak performans sorunlarına sebep olur.

        new Thread(new Runnable() {
            @Override
            public void run() {
                ThreadSafeSyncronized.getInstance().sampleMethodA();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                ThreadSafeSyncronized.getInstance().sampleMethodB();
            }
        }).start();

Yukarıdaki şekilde çağırdığımızda resimde görüleceği gibi threadlerin birbirini blokladığını görüyoruz.

thread block sample.

Thread safe singleton’a bir diğer yaklaşım ise double check yöntemidir. Bu yöntemde sadece instance oluşturulurken sınıf senkronize edileceğinden performans sorununa da yol açmaz.

package codegenius;

/**
 *
 * @author codegeni.us
 */
public class ThreadSafeDoubleCheck {

    private static ThreadSafeDoubleCheck instance;

    private ThreadSafeDoubleCheck() {
    }

    public static ThreadSafeDoubleCheck getInstance() {

        if (instance == null) {

            synchronized (ThreadSafeDoubleCheck.class) {
                if (instance == null) {
                    instance = new ThreadSafeDoubleCheck();
                }
            }
        }

        return instance;
    }
}

 

5. Bill Pugh Singleton Yöntemi

Java 5 ve öncesi bellek modelindeki problemden dolayı singleton sınıfına eş zamanlı erişilmeye çalışıldığında sorunlar ortaya çıkıyordu. Bu neden Bill Pugh yardımcı nested sınıf kullanarak singleton yapısı oluşturdu. Böylece sınıfın instance’ı yardımcı sınıfta tutuluyor. Sadece sınıf çağırıldığı zaman yardımcı sınıftan faydalanılarak instance çağrılıyordu. Böylece sınıfın yüklenme zamanında instance oluşmuyor sadece erişilmeye çalışıldığında oluşturuluyordu. Bu yöntemle geliştirilmiş singleton patterni aşağıdaki gibidir:

package codegenius;

/**
 *
 * @author codegeni.us
 */
public class BillPugh {

    private BillPugh() {
    }

    private static class SingletonHelper {

        private static final BillPugh instance = new BillPugh();
    }

    public static BillPugh getInstance() {
        return SingletonHelper.instance;
    }
}

Singleton sınıfı belleğe yüklendiğinde yardımcı inner sınıf belleğe yüklenmez. Sadece birisi getInstance metodunu çağırdığında yüklenir. Böylece senkronizasyon yapmaya da gerek kalmaz. Genelde en çok kullanılan java singleton patterni budur.

Kaynak: JournalDev

İyi kodlamalar,

Loading

Facebooktwitterredditpinterestlinkedinmail

Kod yazmak anlamaktır.