Etkinlik Bağlamı ve Uygulama Bağlamı Arasındaki Fark


233

Bu beni çok üzdü, bunu Android 2.1-r8 SDK'da kullanıyordum:

ProgressDialog.show(getApplicationContext(), ....);

ve ayrıca

Toast t = Toast.makeText(getApplicationContext(),....);

kullanarak getApplicationContext()kilitlenmeleri hem ProgressDialogve Toastbu soruya bana yol ....:

'Bağlam' ifadesini paylaşmasına rağmen, bir etkinlik bağlamı ile uygulama bağlamı arasındaki gerçek farklar nelerdir?



14
Bu, bazı şeyleri temizlemeye yardımcı olmalıdır: Bağlam, Hangi Bağlam?
toobsco42

Yanıtlar:


250

Her ikisi de Bağlam örneğidir , ancak uygulama örneği uygulamanın yaşam döngüsüne bağlanırken, Etkinlik örneği bir Etkinliğin yaşam döngüsüne bağlıdır. Böylece uygulama ortamıyla ilgili farklı bilgilere erişebilirler.

GetApplicationContext adresindeki belgeleri okursanız, bunu yalnızca yaşam döngüsü geçerli içerikten ayrı bir içeriğe ihtiyacınız varsa kullanmanız gerektiğini belirtir. Bu, örneklerinizin hiçbirinde geçerli değildir.

Etkinlik bağlamında, söz konusu çağrıları tamamlamak için gerekli olan mevcut etkinlik hakkında bazı bilgiler vardır. Tam hata mesajını gösterirseniz, tam olarak neye ihtiyaç duyduğunu gösterebilir.

Ancak genel olarak, yapmamak için iyi bir nedeniniz yoksa etkinlik bağlamını kullanın.


1
Oldukça getApplicationContextilginç bir şekilde kullandığımda , 'java.lang.reflect.InvocationTargetException' aldım , ilginç bir şekilde, değiştirdiğimde thisçökmedi ve beklendiği gibi çalışmadı ... diğeri? Bu bilgi başkalarına yardımcı olacaktır umarım ... :) hızlı cevap için teşekkürler ...
t0mm13b

2
Bir şey söyleyebilmek için tüm istisna yığın izini görmem gerekir. Ancak, dediğim gibi, bağlam örneklerinin farklı bilgileri vardır. Muhtemelen ekranda bir iletişim kutusu veya tost göstermek için yalnızca Etkinlik örneğinin sahip olduğu Etkinlik hakkında bilgi gerekir.
Cheryl Simon

74
Çok iyi bir nedeniniz yoksa (yani diyaloglar veya tostlar için) uygulama içeriğini kullanın diyebilirim. Farklı durumlarda aktivite bağlamlarını kullanarak bellek sızıntılarına girmek oldukça kolaydır, bu yüzden güvende olmak en iyisidir :) android-developers.blogspot.com/2009/01/…
Dori

10
Dave Smith, bağlamın kullanımını anlamak için çok iyi bir blog girişi yayınladı, buraya bakın . Yorumları da okuduğunuzdan emin olun!
ChrLipp

1
Mesele şu ki, Dianna Hackborn bile aktivite bağlamının kullanılmasını önermektedir. stackoverflow.com/questions/5228160/… Ama kendisi bundan tam olarak emin değil gibi görünüyor.
JacksOnF1re

178

Bu tabloyu farklı bağlamlarda ne zaman kullanacağınıza karar vermek için süper yararlı buldum:

resim açıklamasını buraya girin

  1. Bir uygulama buradan Etkinlik başlatabilir, ancak yeni bir görevin oluşturulmasını gerektirir. Bu, belirli kullanım durumlarına uyabilir, 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ı null ise izin verilir.

Orijinal makale burada .



kaynakları almaya ne dersin? bence onu masanıza eklemeniz daha iyi. kaynaklara applciation bağlamıyla erişebilirsiniz.
Amir Ziarati

Etkinliğe Uygulama bağlamından başlayabiliriz
Duy Phan

Makale burada da bulunabilir: wundermanthompsonmobile.com/2013/06/context
Lifes

34

Bu açıkça API tasarımının eksikliğidir. İlk olarak, Etkinlik Bağlamı ve Uygulama bağlamı tamamen farklı nesnelerdir, bu nedenle bağlamın kullanıldığı yöntem parametrelerinin üst sınıf Bağlamı kullanmak yerine ApplicationContextveya Activitydoğrudan kullanılması gerekir . İkinci olarak, doküman hangi bağlamın açıkça kullanılacağını veya kullanılamayacağını belirtmelidir.


25
Kesinlikle katılmak. Google topu bu yere attı. Tam bir karmaşa.
Søren Boisen

@ SørenBoisen android sdk tam bir karmaşa
CommonSenseCode

Dağınıklığın farkındalar ve emin olmak için ellerinden geleni yapmakta zorlanıyorlar.
pasignature

15

Bence aktivitesi yok edildikten sonra iletişim kutusu olarak kalamayacağı ProgressDialogkadar etkinliğe bağlı olan aktiviteye bağlı olduğu için aktiviteyle de yok edilen (ActivityContext) ProgressDialogiletilmesi gerekir this(ActivityContext). yerlebir edilmiş.


3

Kendisinin genel kapsamı olacağı bir Bağlama bağlı bir şeye ihtiyacınız varsa getApplicationContext () öğesini kullanın.

Etkinlik'i kullanırsanız, yeni Etkinlik örneğinin eski Etkinliğe örtük başvurusu olan bir başvurusu olur ve eski Etkinlik çöp toplanamaz.


2

Sanırım her şey göstermek için bir ekrana ihtiyaç duyduğunda (düğme, iletişim kutusu, düzen ...) içerik etkinliğini kullanmak zorundayız ve her şeyin göstermek veya işlemek için bir ekrana ihtiyacı yok (tost, servis telefonu, iletişim ...) biz uygulama bağlamını kullanabilir


1

Uygulamanızı doğrudan ana ekrandan başlattığınızda, uygulamanız paylaşım amacı ile başka bir uygulamadan başlatıldığında iki bağlam arasında bir fark görebilirsiniz.

@CommonSenseCode tarafından belirtilen "standart olmayan arka yığın davranışlarının" ne anlama geldiğine dair pratik bir örnek:

Eğer birbirleri ile iletişim iki uygulamalarım var olduğunu varsayalım Uyg1 ve Uyg2 .

Başlatıcıdan App2: MainActivity'yi başlatın . Ardından MainActivity'den App2 : SeincilActivity'yi başlatın . Burada, etkinlik bağlamı veya uygulama bağlamı kullanılarak, her iki etkinlik de aynı görevde yaşar ve bu tamamdır (tüm standart başlatma modlarını ve niyet bayraklarını kullanmanız şartıyla). MainActivity'ye bir geri basışla geri dönebilirsiniz ve son uygulamalarda yalnızca bir göreviniz vardır.

Eğer olduklarını şimdi varsayalım Uyg1 ve fırlatma MainActivity: Uyg2 niyet payı (ACTION_SEND veya ACTION_SEND_MULTIPLE) ile. Daha sonra App2: SelementaryActivity'yi (her zaman tüm standart başlatma modları ve niyet bayrakları ile) başlatmaya çalışın . Ne olur:

  • Android <10'da App2: SeincilActivity'yi uygulama bağlamıyla başlatırsanız, tüm görevleri aynı görevde başlatamazsınız . Android 7 ve 8 ile denedim ve SelementaryActivity her zaman yeni bir görevde başlatılır (Sanırım App2: SeincilActivity, App2 uygulama bağlamıyla başlatıldı, ancak App1'den geliyorsunuz ve App2 uygulamasını doğrudan başlatmadınız Belki kaputun altında android bunu tanır ve FLAG_ACTIVITY_NEW_TASK kullanır). İhtiyaçlarınıza bağlı olarak bu iyi veya kötü olabilir, çünkü uygulamam kötüydü.
    Android'de 10 günü uygulaması çöküyor mesajla
    "FLAG_ACTIVITY_NEW_TASK bayrak bir Etkinlik kapsamında dışından startActivity () çağrılması gerekir. Bu İstediğin gerçekten var mı?" .
    Bu nedenle, Android 10'da çalışmasını sağlamak için FALG_ACTIVITY_NEW_TASK kullanmanız gerekir ve tüm görevleri aynı görevde çalıştıramazsınız.
    Gördüğünüz gibi davranış android sürümleri arasında farklı, garip.

  • App2: SeATIONALActivity'yi etkinlik bağlamıyla başlatırsanız tüm işler iyi gider ve tüm görevleri aynı görevde çalıştırarak doğrusal bir backstack navigasyonu elde edebilirsiniz.

Umarım faydalı bilgiler ekledim

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.