Etkinlik Yaşam Döngüsü

Etkinlikler, Android uygulamalarının temel yapı taşlarıdır ve bir dizi farklı durumda bulunabilir. Etkinlik yaşam döngüsü örnekleme ile başlar ve yok etme ile biter ve arada birçok durum içerir. Bir etkinlik durumu değiştirdiğinde, yaklaşan durum değişikliğinin etkinliğini bilgilendiren ve bu değişikliğe uyum sağlamak için kod yürütmesine izin veren uygun yaşam döngüsü olay yöntemi çağrılır. Bu makalede etkinliklerin yaşam döngüsü incelenir ve bu durumların her biri sırasında bir etkinliğin sahip olduğu sorumluluk iyi davranılmış, güvenilir bir uygulamanın parçası olarak değişir.

Etkinlik Yaşam Döngüsüne Genel Bakış

Etkinlikler, Android'e özgü olağan dışı bir programlama kavramıdır. Geleneksel uygulama geliştirmede genellikle uygulamayı başlatmak için yürütülen statik bir ana yöntem vardır. Ancak Android ile işler farklıdır; Android uygulamaları, bir uygulama içindeki herhangi bir kayıtlı etkinlik aracılığıyla başlatılabilir. Uygulamada çoğu uygulama yalnızca uygulama giriş noktası olarak belirtilen belirli bir etkinliğe sahip olur. Ancak, bir uygulama kilitlenirse veya işletim sistemi tarafından sonlandırılırsa, işletim sistemi uygulamayı son açık etkinlikte veya önceki etkinlik yığını içinde başka bir yerde yeniden başlatmayı deneyebilir. Ayrıca, işletim sistemi etkin olmayan etkinlikleri duraklatabilir ve bellek yetersizse geri kazanabilir. Özellikle bu etkinlik önceki etkinliklere ait verilere bağlıysa, bir etkinliğin yeniden başlatılması durumunda uygulamanın durumunu doğru bir şekilde geri yüklemesine izin vermek için dikkatli bir şekilde dikkate alınmalıdır.

Etkinlik yaşam döngüsü, bir etkinliğin yaşam döngüsü boyunca işletim sisteminin çağırdiği bir yöntem koleksiyonu olarak uygulanır. Bu yöntemler, geliştiricilerin uygulamalarının durum ve kaynak yönetimi gereksinimlerini karşılamak için gereken işlevselliği uygulamasına olanak tanır.

Uygulama geliştiricisinin her etkinliğin gereksinimlerini analiz ederek etkinlik yaşam döngüsü tarafından kullanıma sunulan yöntemlerin uygulanması gerektiğini belirlemesi son derece önemlidir. Bunun yapılmaması, uygulama kararlılığına, kilitlenmelere, kaynak şişmesine ve hatta büyük olasılıkla temel işletim sistemi kararlılığına neden olabilir.

Bu bölümde etkinlik yaşam döngüsü ayrıntılı olarak incelenerek:

  • Etkinlik Durumları
  • Yaşam Döngüsü Yöntemleri
  • Uygulamanın Durumunu Koruma

Bu bölüm ayrıca Etkinlik yaşam döngüsü sırasında durumu verimli bir şekilde kaydetme hakkında pratik örnekler sağlayan bir kılavuz içerir. Bu bölümün sonunda Etkinlik yaşam döngüsü ve bir Android uygulamasında nasıl desteklenmeleri gerektiği hakkında bilgi sahibi olmanız gerekir.

Etkinlik Yaşam Döngüsü

Android etkinlik yaşam döngüsü, geliştiriciye bir kaynak yönetimi çerçevesi sağlayan Etkinlik sınıfı içinde kullanıma sunulan bir yöntem koleksiyonundan oluşur. Bu çerçeve, geliştiricilerin uygulama içindeki her etkinliğin benzersiz durum yönetimi gereksinimlerini karşılamasına ve kaynak yönetimini düzgün bir şekilde işlemesine olanak tanır.

Etkinlik Durumları

Android işletim sistemi, Etkinlikleri durumlarına göre rastgele belirler. Bu, Android'in artık kullanılmayan etkinlikleri tanımlamasına yardımcı olur ve işletim sisteminin belleği ve kaynakları geri kazanmasını sağlar. Aşağıdaki diyagramda bir Etkinliğin yaşam süresi boyunca geçirebileceği durumlar gösterilmektedir:

Activity states diagram

Bu durumlar aşağıdaki gibi 4 ana gruba ayrılabilir:

  1. Etkin veya Çalışıyor – Etkinlikler, etkinlik yığınının üst kısmı olarak da bilinen ön plandaysa etkin veya çalışır olarak kabul edilir. Bu, Android'deki en yüksek öncelikli etkinlik olarak kabul edilir ve bu nedenle, kullanıcı arabiriminin yanıt vermemeye başlamasına neden olabileceğinden, etkinliğin cihazda bulunandan daha fazla bellek kullanmaya çalışması gibi aşırı durumlarda işletim sistemi tarafından öldürülür.

  2. Duraklatıldı – Cihaz uyku moduna geçtiğinde veya bir etkinlik hala görünürken yeni, tam boyutlu olmayan veya saydam bir etkinlik tarafından kısmen gizlendiğinde, etkinlik duraklatılmış olarak kabul edilir. Duraklatılan etkinlikler hala etkindir, yani tüm durum ve üye bilgilerini korur ve pencere yöneticisine bağlı kalır. Bu, Android'deki ikinci en yüksek öncelikli etkinlik olarak kabul edilir ve bu nedenle işletim sistemi tarafından yalnızca bu etkinliği öldürmek Etkin/Çalışan Etkinliği kararlı ve esnek tutmak için gereken kaynak gereksinimlerini karşılayacaksa öldürülür.

  3. Durduruldu/Arka Planlı – Başka bir etkinlik tarafından tamamen gizlenen etkinlikler durdurulmuş veya arka planda kabul edilir. Durdurulan etkinlikler yine de durum ve üye bilgilerini mümkün olduğunca uzun süre saklamaya çalışır, ancak durdurulan etkinlikler üç durumun en düşük önceliği olarak kabul edilir ve bu nedenle işletim sistemi, daha yüksek öncelikli etkinliklerin kaynak gereksinimlerini karşılamak için önce bu durumdaki etkinlikleri öldürür.

  4. Yeniden başlatıldı – Yaşam döngüsünde duraklatılmış olan ve durdurulan bir etkinliğin Android tarafından bellekten kaldırılması mümkündür. Kullanıcı etkinliğe geri giderse yeniden başlatılması, daha önce kaydedilmiş durumuna geri yüklenmesi ve ardından kullanıcıya görüntülenmesi gerekir.

Yapılandırma Değişikliklerine Yanıt Olarak Etkinlik Yeniden Oluşturma

Daha karmaşık hale getirmek için Android, Yapılandırma Değişiklikleri adlı karmaya bir anahtar daha atar. Yapılandırma değişiklikleri, cihazın döndürülmesi (ve etkinliğin yatay veya dikey modda yeniden oluşturulması gerekir), klavye görüntülendiğinde (ve etkinliğin kendisini yeniden boyutlandırma fırsatı sunulduğunda) veya cihaz bir takma birimine yerleştirildiğinde bir etkinliğin yapılandırması değiştiğinde oluşan hızlı etkinlik yok etme/yeniden oluşturma döngüleridir. diğerleriyle birlikte.

Yapılandırma değişiklikleri, etkinliğin durdurulması ve yeniden başlatılması sırasında yine aynı Etkinlik Durumu değişikliklerinin oluşmasına neden olur. Ancak, bir uygulamanın hızlı yanıt verme ve yapılandırma değişiklikleri sırasında iyi performans göstermesini sağlamak için, bunların mümkün olan en hızlı şekilde işlenmesi önemlidir. Bu nedenle, Android yapılandırma değişiklikleri sırasında durumu kalıcı hale getirmek için kullanılabilecek belirli bir API'ye sahiptir. Bunu daha sonra Yaşam Döngüsü Boyunca Durumu Yönetme bölümünde ele alacağız.

Etkinlik Yaşam Döngüsü Yöntemleri

Android SDK ve uzantıya göre Xamarin.Android çerçevesi, uygulama içindeki etkinliklerin durumunu yönetmek için güçlü bir model sağlar. Bir etkinliğin durumu değiştiğinde, etkinliğe ilgili etkinlikte belirli yöntemleri çağıran işletim sistemi tarafından bildirim gönderilir. Aşağıdaki diyagramda, Etkinlik Yaşam Döngüsü ile ilgili olarak bu yöntemler gösterilmektedir:

Activity Lifecycle flowchart

Geliştirici olarak, bir etkinlik içinde bu yöntemleri geçersiz kılarak durum değişikliklerini işleyebilirsiniz. Bununla birlikte, tüm yaşam döngüsü yöntemlerinin kullanıcı arabirimi iş parçacığında çağrıldığını ve işletim sisteminin geçerli etkinliği gizleme, yeni bir etkinlik görüntüleme gibi bir sonraki kullanıcı arabirimi çalışmasını gerçekleştirmesini engelleyeceğini unutmayın. Bu nedenle, bir uygulamanın iyi performans göstermesini sağlamak için bu yöntemlerdeki kod mümkün olduğunca kısa olmalıdır. Uzun süre çalışan görevler arka plan iş parçacığında yürütülmelidir.

Şimdi bu yaşam döngüsü yöntemlerinin her birini ve bunların kullanımını inceleyelim:

Oncreate

OnCreate , bir etkinlik oluşturulduğunda çağrılan ilk yöntemdir. OnCreate gibi bir Etkinliğin gerektirebileceği başlatma başlatma işlemlerini gerçekleştirmek için her zaman geçersiz kılınır:

  • Görünüm oluşturma
  • Değişkenleri başlatma
  • Statik verileri listelere bağlama

OnCreate, etkinlikler arasında durum bilgilerini ve nesneleri depolamak ve geçirmek için kullanılan bir sözlük olan Bundle parametresini alır Paket null değilse, bu, etkinliğin yeniden başlatıldığına ve önceki örnekten durumunu geri yüklemesi gerektiğine işaret eder. Aşağıdaki kod, paketten değerleri alma işlemini gösterir:

protected override void OnCreate(Bundle bundle)
{
   base.OnCreate(bundle);

   string intentString;
   bool intentBool;

   if (bundle != null)
   {
      intentString = bundle.GetString("myString");
      intentBool = bundle.GetBoolean("myBool");
   }

   // Set our view from the "main" layout resource
   SetContentView(Resource.Layout.Main);
}

İşlem tamamlandıktan sonra OnCreate Android çağrısı OnStartyapacaktır.

Onstart

OnStart , tamamlandıktan sonra OnCreate sistem tarafından her zaman çağrılır. Etkinlikler, etkinlik içindeki görünümlerin geçerli değerlerini yenileme gibi belirli görevleri bir etkinlik görünür hale gelmeden hemen önce gerçekleştirmeleri gerekiyorsa bu yöntemi geçersiz kılabilir. Android, bu yöntemden hemen sonra çağrı OnResume yapacaktır.

OnResume

Etkinlik kullanıcıyla etkileşim kurmaya hazır olduğunda sistem OnResume'ı çağırır. Etkinlikler aşağıdaki gibi görevleri gerçekleştirmek için bu yöntemi geçersiz kılmalıdır:

  • Kare hızlarını artırma (oyun geliştirmede ortak bir görev)
  • Animasyonları başlatma
  • GPS güncelleştirmelerini dinleme
  • İlgili uyarıları veya iletişim kutularını görüntüleme
  • Dış olay işleyicilerini bağla

Örneğin, aşağıdaki kod parçacığı kameranın nasıl başlatılmış olduğunu gösterir:

protected override void OnResume()
{
    base.OnResume(); // Always call the superclass first.

    if (_camera==null)
    {
        // Do camera initializations here
    }
}

OnResume içinde yapılan OnPause tüm işlemlerin içinde OnResumeyapılmaması gerektiğinden önemlidir çünkü etkinliği yeniden hayata geçirdikten sonra OnPause yürütülmesi garanti edilen tek yaşam döngüsü yöntemidir.

Onpause

Sistem etkinliği arka plana koymak üzere olduğunda veya etkinlik kısmen gizlendiğinde OnPause çağrılır. Etkinlikler aşağıdakilere ihtiyaç duyarsa bu yöntemi geçersiz kılmalıdır:

  • Kaydedilmemiş değişiklikleri kalıcı verilere işleme

  • Kaynakları tüketen diğer nesneleri yok etme veya temizleme

  • Kare hızlarını azaltma ve animasyonları duraklatma

  • Dış olay işleyicilerinin veya bildirim işleyicilerinin (bir hizmete bağlı olanlar) kaydını kaldırın. Etkinlik bellek sızıntılarını önlemek için bu yapılmalıdır.

  • Benzer şekilde, Etkinlik herhangi bir iletişim kutusu veya uyarı görüntülediyse, bunların yöntemiyle .Dismiss() temizlenmesi gerekir.

Örneğin, aşağıdaki kod parçacığı kamerayı serbest bırakır; etkinlik duraklatılırken kamerayı kullanamaz:

protected override void OnPause()
{
    base.OnPause(); // Always call the superclass first

    // Release the camera as other activities might need it
    if (_camera != null)
    {
        _camera.Release();
        _camera = null;
    }
}

'den sonra OnPauseçağrılabilecek iki olası yaşam döngüsü yöntemi vardır:

  1. OnResume etkinliği ön plana döndürülecekse çağrılır.
  2. OnStop , Etkinlik arka plana yerleştiriliyorsa çağrılır.

Onstop

Etkinlik artık kullanıcıya görünmediğinde OnStop çağrılır. Aşağıdakilerden biri oluştuğunda bu durum oluşur:

  • Yeni bir etkinlik başlatılıyor ve bu etkinliği kapsıyor.
  • Mevcut bir etkinlik ön plana getiriliyor.
  • Etkinlik yok ediliyor.

OnStop Android'in kaynaklar için yetersiz kalması ve Etkinliği düzgün bir şekilde arka planlayamaması gibi düşük bellekli durumlarda her zaman çağrılamayabilir. Bu nedenle, imha için bir Etkinlik hazırlarken çağrılmaya güvenmemek OnStop en iyisidir. Bundan OnDestroy sonra çağrılabilecek bir sonraki yaşam döngüsü yöntemleri, Etkinlik'in yok olması veya OnRestart Etkinlik'in kullanıcıyla etkileşime geçmek için geri gelmesi olacaktır.

OnDestroy

OnDestroy , yok edilmeden ve bellekten tamamen kaldırılmadan önce etkinlik örneğinde çağrılan son yöntemdir. Aşırı durumlarda Android, Etkinliği barındıran uygulama işlemini sonlandırabilir ve bu da çağrılmamayla sonuçlanır OnDestroy . Çoğu temizleme ve kapatma işlemi ve OnStop yöntemlerinde yapıldığından OnPause çoğu Etkinlik bu yöntemi uygulamaz. OnDestroy Yöntem genellikle kaynakları sızdırabilecek uzun süre çalışan görevleri temizlemek için geçersiz kılındı. Bunun bir örneği, içinde OnCreatebaşlatılan arka plan iş parçacıkları olabilir.

Etkinlik yok edildikten sonra çağrılan yaşam döngüsü yöntemi yoktur.

OnRestart

OnRestart , etkinliğiniz durdurulduktan sonra, yeniden başlatılmadan önce çağrılır. Bunun iyi bir örneği, kullanıcının uygulamadaki bir etkinliğin üzerindeyken giriş düğmesine basması olabilir. Bu olduğunda OnPause ve ardından OnStop yöntemler çağrıldığında ve Etkinlik arka plana taşındığında ancak yok edilmediğinde. Kullanıcı daha sonra görev yöneticisini veya benzer bir uygulamayı kullanarak uygulamayı geri yüklediyse, Android etkinliğin OnRestart yöntemini çağırır.

içinde ne tür bir mantığın uygulanması OnRestartgerektiğine ilişkin genel yönergeler yoktur. Bunun nedeniOnStart, Etkinliğin oluşturulup oluşturulmadığına veya yeniden başlatılmasına bakılmaksızın her zaman çağrılır, bu nedenle Etkinliğin gerektirdiği tüm kaynaklar yerine OnRestartiçinde OnStartbaşlatılmalıdır.

sonra çağrılan OnRestart sonraki yaşam döngüsü yöntemi olacaktır OnStart.

Geri ve Giriş karşılaştırması

Birçok Android cihazın iki ayrı düğmesi vardır: "Geri" düğmesi ve "Giriş" düğmesi. Bunun bir örneği, Android 4.0.3'ün aşağıdaki ekran görüntüsünde görülebilir:

Back and Home buttons

Bir uygulamayı arka plana yerleştirmenin aynı etkisine sahip gibi görünseler de, iki düğme arasında ince bir fark vardır. Bir kullanıcı Geri düğmesine tıkladığında, Android'e etkinliği tamamladıklarını söyler. Android, Etkinliği yok edecektir. Buna karşılık, kullanıcı Giriş düğmesine tıkladığında etkinlik yalnızca arka plana yerleştirilir – Android etkinliği sonlandırmaz.

Yaşam Döngüsü Boyunca Durumu Yönetme

Bir Etkinlik durdurulduğunda veya yok edildiğinde sistem, Etkinliğin durumunu daha sonra yeniden doldurma için kaydetme fırsatı sağlar. Bu kaydedilen durum örnek durumu olarak adlandırılır. Android, Etkinlik yaşam döngüsü sırasında örnek durumunu depolamak için üç seçenek sunar:

  1. Temel değerleri Android'in durumu kaydetmek için kullanacağı Paket olarak bilinen bir Dictionary pakette depolama.

  2. Bit eşlemler gibi karmaşık değerleri barındıracak özel bir sınıf oluşturma. Android, durumu kaydetmek için bu özel sınıfı kullanır.

  3. Yapılandırma değişikliği yaşam döngüsünü aşma ve etkinlikte durumu koruma sorumluluğunun tamamını üstlenme.

Bu kılavuzda ilk iki seçenek yer alır.

Paket Durumu

Örnek durumunu kaydetmek için birincil seçenek, Paket olarak bilinen bir anahtar/değer sözlüğü nesnesi kullanmaktır. Bir Etkinlik oluşturulduğunda yöntemin OnCreate parametre olarak bir pakete geçirildiğini unutmayın, bu paket örnek durumunu geri yüklemek için kullanılabilir. Anahtar/değer çiftleri (bit eşlemler gibi) için hızlı veya kolay seri hale getirilmeyecek daha karmaşık veriler için bir paket kullanılması önerilmez; bunun yerine, dizeler gibi basit değerler için kullanılmalıdır.

Etkinlik, Paketteki örnek durumunu kaydetmeye ve almaya yardımcı olacak yöntemler sağlar:

  • OnSaveInstanceState – Etkinlik yok edilirken Android tarafından çağrılır. Etkinlikler herhangi bir anahtar/değer durumu öğesini kalıcı hale getirmek için bu yöntemi uygulayabilir.

  • OnRestoreInstanceState – Bu yöntem tamamlandıktan sonra OnCreate çağrılır ve başlatma tamamlandıktan sonra bir Etkinliğin durumunu geri yüklemesi için başka bir fırsat sağlar.

Aşağıdaki diyagramda bu yöntemlerin nasıl kullanıldığı gösterilmektedir:

Bundle states flowchart

OnSaveInstanceState

Etkinlik durdurulurken OnSaveInstanceState çağrılır. Etkinlik'in durumunu depolayabildiği bir paket parametresi alır. Bir cihaz yapılandırma değişikliğiyle karşılaştığında, bir Etkinlik geçersiz kılarak OnSaveInstanceStateEtkinlik durumunu korumak için geçirilen nesnesini kullanabilirBundle. Örneğin, aşağıdaki kodu göz önünde bulundurun:

int c;

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);

  this.SetContentView (Resource.Layout.SimpleStateView);

  var output = this.FindViewById<TextView> (Resource.Id.outputText);

  if (bundle != null) {
    c = bundle.GetInt ("counter", -1);
  } else {
    c = -1;
  }

  output.Text = c.ToString ();

  var incrementCounter = this.FindViewById<Button> (Resource.Id.incrementCounter);

  incrementCounter.Click += (s,e) => {
    output.Text = (++c).ToString();
  };
}

Yukarıdaki kod, adlı bir düğmeye tıklandığında adlı c incrementCounter bir tamsayıyı artırır ve sonucu adlandırılmış outputolarak TextView görüntüler. Bir yapılandırma değişikliği gerçekleştiğinde (örneğin, cihaz döndürüldüğünde) yukarıdaki kod değerini c kaybeder çünkü bundle aşağıdaki şekilde gösterildiği gibi değeri olacaktır null:

Display does not show previous value

Bu örnekte değerini c korumak için Etkinlik, değerini aşağıda gösterildiği gibi pakete kaydederek değerini geçersiz kılabilir OnSaveInstanceState:

protected override void OnSaveInstanceState (Bundle outState)
{
  outState.PutInt ("counter", c);
  base.OnSaveInstanceState (outState);
}

Cihaz yeni bir yönlendirmeye döndürüldüğünde, tamsayı pakete kaydedilir ve şu satırla alınır:

c = bundle.GetInt ("counter", -1);

Not

Görünüm hiyerarşisinin durumunun da kaydedilebilmesi için her zaman temel uygulamasını OnSaveInstanceState çağırmak önemlidir.

Durumu Görüntüle

Geçersiz kılma OnSaveInstanceState , yukarıdaki örnekteki sayaç gibi yönlendirme değişiklikleri arasında bir Etkinlikte geçici verileri kaydetmek için uygun bir mekanizmadır. Ancak varsayılan uygulaması OnSaveInstanceState , her görünümün atanmış bir kimliği olduğu sürece her görünüm için geçici verileri kullanıcı arabirimine kaydetmeyi üstlenir. Örneğin, bir uygulamanın XML'de aşağıdaki gibi tanımlanmış bir EditText öğesi olduğunu varsayalım:

<EditText android:id="@+id/myText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"/>

EditText Denetim id atanmış olduğundan, kullanıcı bazı veriler girip cihazı döndürüyorsa, veriler aşağıda gösterildiği gibi görüntülenmeye devam eder:

Data is preserved in landscape mode

OnRestoreInstanceState

OnRestoreInstanceState , sonrasında OnStartçağrılır. Bir etkinliğe, daha önce önceki OnSaveInstanceStatesırasında bir Pakete kaydedilmiş olan tüm durumları geri yükleme fırsatı sağlar. Ancak bu, için OnCreatesağlanan paketle aynıdır.

Aşağıdaki kod, içinde OnRestoreInstanceStatedurumun nasıl geri yüklenebileceğini gösterir:

protected override void OnRestoreInstanceState(Bundle savedState)
{
    base.OnRestoreInstanceState(savedState);
    var myString = savedState.GetString("myString");
    var myBool = savedState.GetBoolean("myBool");
}

Bu yöntem, durumun ne zaman geri yükleneceği konusunda biraz esneklik sağlamak için mevcuttur. Bazen örnek durumunu geri yüklemeden önce tüm başlatmalar yapılana kadar beklemek daha uygundur. Ayrıca, mevcut bir Etkinliğin alt sınıfı yalnızca örnek durumundan belirli değerleri geri yüklemek isteyebilir. Çoğu etkinlik için sağlanan OnCreatepaketi kullanarak durumu geri yükleyebildiğinden çoğu durumda geçersiz kılmak OnRestoreInstanceStategerekli değildir.

kullanarak Bundledurum kaydetme örneği için İzlenecek Yol - Etkinlik durumunu kaydetme bölümüne bakın.

Paket Sınırlamaları

Geçici verileri kaydetmeyi kolaylaştırsa OnSaveInstanceState da bazı sınırlamaları vardır:

  • Her durumda çağrılmaz. Örneğin, Bir Etkinlik'den çıkmak için Giriş veya Geri tuşlarına basıldığında çağrılmazOnSaveInstanceState.

  • içine OnSaveInstanceState geçirilen paket, görüntüler gibi büyük nesneler için tasarlanmamıştır. Büyük nesneler söz konusu olduğunda, aşağıda açıklandığı gibi, nesnenin OnRetainNonConfigurationInstance'tan kaydedilmesi tercih edilir.

  • Paket kullanılarak kaydedilen veriler serileştirilir ve bu da gecikmelere neden olabilir.

Paket durumu, çok fazla bellek kullanmayan basit veriler için kullanışlıdır, yapılandırma dışı örnek verileri ise daha karmaşık veriler veya web hizmeti çağrısı veya karmaşık bir veritabanı sorgusu gibi alınması pahalı veriler için kullanışlıdır. Yapılandırma dışı örnek verileri gerektiğinde bir nesneye kaydedilir. Sonraki bölümde, yapılandırma değişiklikleri aracılığıyla daha karmaşık veri türlerini korumanın bir yolu olarak tanıtabilirsiniz OnRetainNonConfigurationInstance .

Karmaşık Verileri Kalıcı Hale Ekleme

Android, paketteki verileri kalıcı hale getirmek için OnRetainNonConfigurationInstance'ı geçersiz kılarak ve kalıcı olacak verileri içeren bir Java.Lang.Object örneğini döndürerek verilerin kaydedilmesini de destekler. Durumu kaydetmek için kullanmanın OnRetainNonConfigurationInstance başlıca iki avantajı vardır:

  • 'den OnRetainNonConfigurationInstance döndürülen nesne, bellek bu nesneyi koruduğundan daha büyük, daha karmaşık veri türleriyle iyi performans gösterir.

  • OnRetainNonConfigurationInstance yöntemi isteğe bağlı olarak ve yalnızca gerektiğinde çağrılır. Bu, el ile önbellek kullanmaktan daha ekonomiktir.

kullanımı OnRetainNonConfigurationInstance , web hizmeti çağrıları gibi verileri birden çok kez almanın pahalı olduğu senaryolar için uygundur. Örneğin, Twitter'da arama yapılan aşağıdaki kodu göz önünde bulundurun:

public class NonConfigInstanceActivity : ListActivity
{
  protected override void OnCreate (Bundle bundle)
  {
    base.OnCreate (bundle);
    SearchTwitter ("xamarin");
  }

  public void SearchTwitter (string text)
  {
    string searchUrl = String.Format("http://search.twitter.com/search.json?" + "q={0}&rpp=10&include_entities=false&" + "result_type=mixed", text);

    var httpReq = (HttpWebRequest)HttpWebRequest.Create (new Uri (searchUrl));
    httpReq.BeginGetResponse (new AsyncCallback (ResponseCallback), httpReq);
  }

  void ResponseCallback (IAsyncResult ar)
  {
    var httpReq = (HttpWebRequest)ar.AsyncState;

    using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse (ar)) {
      ParseResults (httpRes);
    }
  }

  void ParseResults (HttpWebResponse httpRes)
  {
    var s = httpRes.GetResponseStream ();
    var j = (JsonObject)JsonObject.Load (s);

    var results = (from result in (JsonArray)j ["results"] let jResult = result as JsonObject select jResult ["text"].ToString ()).ToArray ();

    RunOnUiThread (() => {
      PopulateTweetList (results);
    });
  }

  void PopulateTweetList (string[] results)
  {
    ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
  }
}

Bu kod web'den JSON olarak biçimlendirilmiş sonuçları alır, ayrıştırır ve aşağıdaki ekran görüntüsünde gösterildiği gibi sonuçları bir listede gösterir:

Results displayed on screen

Bir yapılandırma değişikliği gerçekleştiğinde (örneğin, bir cihaz döndürüldüğünde) kod işlemi yineler. Başlangıçta alınan sonuçları yeniden kullanmak ve gereksiz, gereksiz ağ çağrılarına neden olmak için, aşağıda gösterildiği gibi sonuçları kaydetmek için kullanabiliriz OnRetainNonconfigurationInstance :

public class NonConfigInstanceActivity : ListActivity
{
  TweetListWrapper _savedInstance;

  protected override void OnCreate (Bundle bundle)
  {
    base.OnCreate (bundle);

    var tweetsWrapper = LastNonConfigurationInstance as TweetListWrapper;

    if (tweetsWrapper != null) {
      PopulateTweetList (tweetsWrapper.Tweets);
    } else {
      SearchTwitter ("xamarin");
    }

    public override Java.Lang.Object OnRetainNonConfigurationInstance ()
    {
      base.OnRetainNonConfigurationInstance ();
      return _savedInstance;
    }

    ...

    void PopulateTweetList (string[] results)
    {
      ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
      _savedInstance = new TweetListWrapper{Tweets=results};
    }
}

Artık cihaz döndürüldüğünde özgün sonuçlar özelliğinden LastNonConfiguartionInstance alınır. Bu örnekte sonuçlar, içeren bir string[] tweet'lerden oluşur. OnRetainNonConfigurationInstance döndürülmelerini gerektirdiğindenJava.Lang.Object, string[] aşağıda gösterildiği gibi , alt sınıflarına Java.Lang.Objectsahip bir sınıfta sarmalanır:

class TweetListWrapper : Java.Lang.Object
{
  public string[] Tweets { get; set; }
}

Örneğin, aşağıdaki kodda gösterildiği gibi, öğesinden OnRetainNonConfigurationInstance döndürülen nesne olarak bir TextView kullanmaya çalışmak Activity'i sızdıracaktır:

TextView _textView;

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);

  var tv = LastNonConfigurationInstance as TextViewWrapper;

  if(tv != null) {
    _textView = tv;
    var parent = _textView.Parent as FrameLayout;
    parent.RemoveView(_textView);
  } else {
    _textView = new TextView (this);
    _textView.Text = "This will leak.";
  }

  SetContentView (_textView);
}

public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
  base.OnRetainNonConfigurationInstance ();
  return _textView;
}

Bu bölümde, ile basit durum verilerini korumayı Bundleve ile OnRetainNonConfigurationInstancedaha karmaşık veri türlerini kalıcı hale nasıl ekleyebileceğimizi öğrendik.

Özet

Android etkinlik yaşam döngüsü, bir uygulama içindeki etkinliklerin durum yönetimi için güçlü bir çerçeve sağlar, ancak anlamak ve uygulamak zor olabilir. Bu bölümde, bir etkinliğin yaşam süresi boyunca geçirebileceği farklı durumlar ve bu durumlarla ilişkili yaşam döngüsü yöntemleri tanıtıldı. Ardından, bu yöntemlerin her birinde ne tür bir mantığın gerçekleştirilmesi gerektiği konusunda rehberlik sağlanmıştır.