GetContext (), getApplicationContext (), getBaseContext () ve “this” arasındaki fark


Yanıtlar:


528
  • View.getContext(): Görünümün çalışmakta olduğu bağlamı döndürür. Genellikle etkin olan Etkinlik.

  • Activity.getApplicationContext(): Tüm uygulamanın bağlamını döndürür (tüm Etkinliklerin içinde çalıştığı işlem). Yalnızca geçerli Etkinliğe değil, tüm uygulamanın yaşam döngüsüne bağlı bir bağlama ihtiyacınız varsa, geçerli Etkinlik bağlamı yerine bunu kullanın.

  • ContextWrapper.getBaseContext(): Bir Bağlama başka bir bağlam içinden erişmeniz gerekiyorsa, bir BağlamWrapper kullanırsınız. ContextWrapper'a getBaseContext () aracılığıyla erişildiği içeriden belirtilen Context.


59
ve "bu" ne olacak?
CooL i3oY

16
+ CooL i3oY getContext ile aynı
Mikey

13
Aslında ben bağlamın doğru tanımı nedir karıştırıyorum?
Ravi

11
"this" ve getContext () ikisi de aynı
KCRaju

43
thisve getContext()her zaman aynı değildir, örneğin Activity sınıfında kullanabilirsiniz, thisçünkü Activitykaynağını devralır Contextancak yöntem sınıfta getContext()değildir Activity. @mikedroid @KCRaju
nandan

92

Çoğu cevaplar zaten kapsayacak getContext()ve getApplicationContext()ancak getBaseContext () nadiren açıklanmıştır.

Yöntem getBaseContext()yalnızca a ContextWrapper. Android, ContextWrapperaşağıdakileri Contextkullanarak mevcut bir etrafında oluşturulmuş bir sınıf sunar :

ContextWrapper wrapper = new ContextWrapper(context);

A kullanmanın yararı, ContextWrapper“orijinal Bağlamı değiştirmeden davranışı değiştirmenize” izin vermesidir. Örneğin, adlı bir etkinliğiniz varsa, teması farklı olan bir a myActivityoluşturabilirsiniz :ViewmyActivity

ContextWrapper customTheme = new ContextWrapper(myActivity) {
  @Override
  public Resources.Theme getTheme() { 
    return someTheme;
  }
}
View myView = new MyView(customTheme);

ContextWrapperEğer tarafından sağlanan en işlevlerini geçersiz kılmak sağlar çünkü gerçekten güçlüdür Contexterişim kaynaklarına kodu dahil (örneğin openFileInput(), getString()), diğer bileşenlerle etkileşim (örn sendBroadcast(), registerReceiver()), istekler izinleri (örn checkCallingOrSelfPermission()) ve çözme dosya sistemi yerleri (örn getFilesDir()). ContextWrappercihaza / sürüme özgü sorunlar üzerinde çalışmak veya bağlam gerektiren Görünümler gibi bileşenlere tek seferlik özelleştirmeler uygulamak için gerçekten yararlıdır.

GetBaseContext () yöntemi, etrafıContextWrapper saran “base” Bağlamına erişmek için kullanılabilir . Eğer, örneğin, bir sorun olup olmadığını kontrol etmek gerekiyorsa “temel” bağlamına erişmeye gerekebilir Service, Activityya da Application:

public class CustomToast {
  public void makeText(Context context, int resId, int duration) {
    while (context instanceof ContextWrapper) {
      context = context.baseContext();
    }
    if (context instanceof Service)) {
      throw new RuntimeException("Cannot call this from a service");
    }
    ...
  }
}

Veya bir yöntemin “paketlenmemiş” sürümünü çağırmanız gerekirse:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}

17
Bu kabul edilmiş bir cevaptan sonraki en önemli cevap.
0leg

4
Varlığının ContextWrapperAndroid çerçevesinin geliştiricileri tarafından verilen en kötü kararlardan biri olduğunu söyleyebilirim . Doğru şeyi yapmak ve Tek Sorumluluk yönündeki kodu yeniden düzenlemek yerine bütün bir Tanrı Nesneleri ailesi yarattıklarını anladıklarında, miras ağacını derinleştirerek Bağlam davranışını değiştirmeye izin veren çirkin bir hack eklediler. En çirkin kötü yazılım mühendisliği. Bize gelince, geliştiriciler, IMHO hiç kimse kullanmamalıdır getBaseContext()veya ContextWrapper. Eğer - büyük bir "kod kokusu" olduğunu.
Vasiliy

CustomToastKodun tamamını görmek istiyorum . Als :)))
Alston

39

getApplicationContext () - Uygulamada çalışan tüm etkinliklerin bağlamını döndürür.

getBaseContext () - Bağlam'a uygulama içindeki başka bir bağlamdan erişmek istiyorsanız erişebilirsiniz.

getContext () - Bağlam görünümünü yalnızca geçerli çalışan etkinliği döndürür.


1
Pls, A ve B harflerini bağlam tanımınıza dahil eder.
HopefullyHelpful

29

"Bağlamın ne olduğu" sorusu Android evrenindeki en zor sorulardan biridir.

Bağlam, sistem kaynaklarına erişen, uygulamanın statik varlıklarını alan, izinleri denetleyen, kullanıcı arabirimi manipülasyonları gerçekleştiren ve daha pek çok yöntem tanımlar. Özünde, Contextüretimde Tanrı Nesnesi anti-paterninin bir örneğidir.

Hangi türden Contextkullanmamız gerektiğinde, çok karmaşık hale gelir, çünkü Tanrı Nesnesi olmak dışında, Contextalt sınıfların hiyerarşi ağacı Liskov İkame İlkesini vahşice ihlal eder.

Bu blog yazısıContext farklı durumlarda sınıfların uygulanabilirliğini özetlemeye çalışmaktadır .

Tamamlanmak için ana tabloyu bu yazıdan kopyalayayım:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | Application | Activity | Service | ContentProvider | BroadcastReceiver |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
| Show a Dialog              | NO          | YES      | NO      | NO              | NO                |
| Start an Activity          | NO¹         | YES      | NO¹     | NO¹             | NO¹               |
| Layout Inflation           | NO²         | YES      | NO²     | NO²             | NO²               |
| Start a Service            | YES         | YES      | YES     | YES             | YES               |
| Bind to a Service          | YES         | YES      | YES     | YES             | NO                |
| Send a Broadcast           | YES         | YES      | YES     | YES             | YES               |
| Register BroadcastReceiver | YES         | YES      | YES     | YES             | NO³               |
| Load Resource Values       | YES         | YES      | YES     | YES             | YES               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  1. Bir uygulama buradan Etkinlik başlatabilir, ancak yeni bir görevin oluşturulmasını gerektirir. Bu, belirli kullanım durumlarına uygun olabilir, ancak uygulamanızda standart olmayan arka yığın davranışları oluşturabilir ve genellikle önerilmez veya iyi uygulama olarak kabul edilmez.
  2. Bu yasaldır, ancak enflasyon, uygulamanızda tanımlanmış olanlarla değil, üzerinde çalıştığınız sistem için varsayılan temayla yapılır.
  3. Android 4.2 ve sonraki sürümlerde yapışkan bir yayının geçerli değerini elde etmek için kullanılan alıcı boşsa izin verilir.

ekran görüntüsü


Bağlantı kurduğunuz harika blog yazısı!
lejonl

28

Contextyeni oluşturulan bileşenler hakkında Actvityveya Applicationbu bileşenler hakkında bilgi sağlar .

İlgili Contextyeni oluşturulan bileşenlere sağlanmalıdır (olup, uygulama kontekst veya etkinlik bağlamı)

Yana Activitybir alt sınıfıdır Context, birini kullanabilirsiniz thiso etkinliğin içeriği almak için


BaseContext ile ilgili açıklamanız nerede?
IgorGanapolsky

1

Bu dokümanlardan

Kullanmanız gerektiğini anladım:

Bağlam etkinliği yerine bağlam uygulamasını kullanmayı deneyin


0

getApplicationContext ()

bu uygulama seviyesi için kullanılır ve tüm faaliyetlere atıfta bulunur.

getContext () ve getBaseContext ()

büyük olasılıkla aynıdır.Bunlar sadece canlı olan mevcut aktivitelere yönlendirilir.

bu

her zaman geçerli sınıf nesnesine bakın.


0

A Context:

  • uygulaması Android sistemi tarafından sağlanan soyut bir sınıf.
  • Uygulamaya özgü kaynaklara ve sınıflara erişimin yanı sıra, başlatma etkinlikleri, yayınlama ve alma hedefleri gibi uygulama düzeyinde işlemler için çağrılara izin verir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.