TL;DR
Context kelimesinin Türkçe anlamı bağlamdır. Uygulamamızın ortamı ve özellikleri context üzerinden uygulamamıza sağlanır. Uygulamanın tercihleri burada saklanır, uygulama özelindeki kaynaklara ve fonksiyonlara bu arayüz üzerinden erişiriz.
“Context… O… Her yerde”
Context dediğimiz şey, her yerde önümüze çıkıyor. Gerek uygulamamıza gömdüğümüz resimleri almak istediğimizde, gerek bir arayüz elemanı oluşturmak istediğimizde, gerekse de yeni bir aktivite açacak olduğumuzda bizden context istiyor Android sistemi.
“Context, Android sisteminin özüdür”
Context, uygulamanın bağlam bilgilerini global olarak barındıran bir soyut sınıftır. Bu sınıf uygulamalara Android sistemi tarafından sağlanır ve intent başlatabilmek, bazı servisleri çalıştırabilmek, kaynaklara erişebilmek gibi bir çok işlemi yaptırabilir. Context’i bunlara açılan bir kapı veya bunların kullanılmasını sağlayan bir aracı olarak düşünebiliriz.
Android sisteminde neredeyse tüm sınıflar, dolaylı ya da direkt olarak, bu sınıf üzerine kurulmuştur ve özelliklerinden faydalanır. Context üzerine kurulmuş en çok kullandığımız 3 sınıf şunlardır; Activity, Application ve Service.
Peki ya Context’i nerelerde/nasıl kullanıyoruz?
Context sınıfı birçok fonksiyonu hazır bulunduruyor. Bir resmi çekmek istediğimiz zaman eğer Context’e uzanan bir sınıf içerisindeysek (örn; Activity, Application, Service vs.) direkt olarak getString(int)
ya da getDrawable(int)
yapmamız yeterli oluyor fakat Context sınıfına uzanmayan bir sınıf içerisindeysek (örn; Adapter, ViewHolder vs.) bir Context objesi bulup onun üzerinden context.getString(int)
ya da context.getDrawable(int)
şeklinde işlem yapmamız gerekiyor. Nasıl kullandığımız fark etmeden bunun gösterimini şu şekilde yapacağım Context#getString(int)
. Benim çoğunlukla kullandığım 3 yer ise şu şekilde;
1- Bir intent başlatırken.
Yukarıda bahsettiğim üzere bulunduğumuz yere göre Context#startActivity(Intent)
şeklinde kullanabiliyoruz. Bu komut yeni bir Activity başlatıyor ve Activity yığınının en tepesine ekliyor.*
2- Bir kaynak kullanmak istediğimizde.
Uygulamamıza gömdüğümüz bir dizi ya da resmi çekmek istediğimizde direkt olarak Context#getString(int)
ya da Context#getDrawable(int)
şeklinde çekebiliyoruz.
3- Bir sistem servisine ulaşmak istediğimizde.
Örneğin bildirim oluşturmak istiyoruz, bildirim oluşturmak için Android sisteminin sağladığı bir servisi kullanmamız gerekiyor. Bu servise Context üzerinden ulaşmamız gerekiyor. Bunu da şu şekilde kullanıyoruz Context#getSystemService(Class)
. Bildirim oluşturmak sadece bir örnek tabii ki. Daha fazla servisi keşfetmek isterseniz buraya tıklayabilirsiniz.
Kullandığım pratikler neler?
Diğer geliştiricilerden aman aman farklı bir şey yapmıyorum aslında. Bazı değişik yaptığımı düşündüğüm şeyler şunlar;
İlk olarak gereksiz Context parametrelerinden bahsedeyim. RecyclerView içinde Adapter#onCreateViewHolder(ViewGroup, int)
fonksiyonu içinde bir arayüz elemanı oluştururken ilk parametre ile bize verilen parent içindeki Context’i kullanıyorum Adapter oluştururken yeniden gönderip boşuna hafıza kullanmak yerine. ViewHolder içinde ise yine bize verilen view içindeki Context’i kullanıyorum herhangi bir işlem yapacak olduğumda. Böylece tüm Adapter yapılarıma her seferinde Context vermek zorunda kalmıyorum.
İkinci ve son olarak da kodumuzun daha güzel gözükmesi için bir öneri. Context altındaki bazı fonksiyonlar kullanınca kodun okuması zorlaşabiliyor. Bunu engellemek için kullanabildiğim kadar ContextCompat kütüphanesini kullanmaya çalışıyorum. Örneğin mContext.getColor(int)
yazmak yerine ContextCompat.getColor(Context, int)
şeklinde yazıyorum. Böylece kod çok daha okunaklı gözüküyor.