2012-08-22 20 views
10

Android'in sources modelini inceledim.getApplicationContext() öğesini çağırdığınızda aranan kod nerede?

public abstract Context getApplicationContext(); 

ContextWrapper.javaContext.java uzanır getApplicationContext() yöntemin uygulanmasına yol açtı: tip Context bir nesneye

@Override 
    public Context getApplicationContext() { 
     return mBase.getApplicationContext(); 
    } 

Ama mBase referanstır Ne buldum Context soyut yöntemi ile soyut sınıf olmasıdır hangi ContextWrapper yapıcısının başlatıcısı:

public ContextWrapper(Context base) { 
    mBase = base; 
} 

Yani bu mBase başvuru, abstract sınıfını başvuruyor? Eh, sadece ActivitygetApplicationContext() aradığınızda çalıştırılan kod nerede olduğunu anlamıyorum.

+0

Eğer sınıfları nasıl soyut çalışması anlayabiliyor musunuz? Bağlamı genişleten bir yer olan somut bir sınıf var, ve bu yöntemin uygulandığı yerdir. –

+0

Nerede olduğunu merak ediyorum, soyut sınıfların nasıl çalıştığını anlıyorum. – Eugene

cevap

15

Bu ilginç bir polimorfizm örneğidir. baseContext uzanır senin, bu ContextWrapper durumunda burada sağlanan kodu getApplicationContext() bir uygulamasını sağlamak zorundadır olarak

sürece. Bu uygulama var ve the one in ContextImpl. kendisi Context uzanır ContextWrapper, ama aynı zamanda bir ContextWrapper olabilir girdi olarak bir Context (veya Service veya bir Application veya bir sürer:

Eğer verilen kodu okurken O birkaç şey dikkat etmek önemlidir Activity). ContextWrapper hangi tür umurunda değil; Sadece bir yöntem getApplicationContext olduğunu bilir ve sorulduğunda bu yöntemi çağırmak istiyor. (Örneğin, başka ContextWrapper geçti, ama çünkü ContextWrapper Ayrıca sadece yuvalama seviyesini arttırmak istiyorum onun kurucu bir Context, gerektirecektir söylenebilir.)

Application extends ContextWrapper sınıf getApplicationContext() olur demek ki, super(null) çağırır NullPointerException'u bu şekilde bıraktıysa, ContextWrapper'da attachBaseContext(Context) tarafından da ayarlanabilir ve bu da ilginç hale gelir. Her Activity ve Application, attach(Context [...other stuff]) yöntemlerine sahiptir. Bunların her biri, Context ile birlikte attachBaseContext() numaralı telefonu arar. Instrumentation sınıfında

  • , bir ContextImpl bir Application içine oluşturulur ve geçirilir android.app.Instrumentation.newApplication() bulacaksınız.
  • ActivityThread sınıfında,oluşturur ve bu Activity kökünü Context olarak geçirir.
  • LoadedApk sınıfında makeApplication sınıfında, Application'a iletilen bir ContextImpl oluşturur. Aradığı yer Here.

Yani, günün sonunda, mBase tipik bir ContextImpl olarak sona erer.

Potansiyel faydalı linkler bunların hepsini dışarı bulurken baktı:

+0

Cevabınız için teşekkürler, Jon. Kafam karıştı, çünkü bu yöntemin hiçbir uygulaması yok, ne de Application.java'da ne Service.java'da. Uygulama nerede? – Eugene

+1

Uygulama, 'ContextWrapper' içinde. Anahtar bilgi bitimi, bir Aktivite veya Uygulama başlatıldığında "mBase" işleminin çalışma zamanında değişmesidir. –

+0

Böylesine ayrıntılı bir araştırma ve açıklama için teşekkürler! – Eugene

İlgili konular