Android statik nesne yaşam döngüsü


101

Olay arama uygulaması oluşturuyorum, bir ekrandan arama kriterleri belirliyoruz başka bir ekrana yerleştiriyoruz, ardından kullanıcı 3. ekrandan arama kriterlerini düzenleyebiliyor ve 4. ekrana geçiyor.

Yukarıdaki görevi başarmak için uygulamanın etrafındaki değerleri hatırlayan statik nesne kullanıyorum ve fazladan bir şey yapmam gerekmiyor.

Ancak, düşük bellek android statik nesneleri silerseniz, android'de statik nesne yaşam döngüsü hakkında korkuyorum ???

Android çoklu görevi desteklediğinden, kullanıcı başka bir uygulamaya geçerse ve kullanıcı geri döndüğünde uygulama deli gibi davranmaya başlarsa, çoklu görev olduğunda statik nesne kaldırılır mı ??? Herhangi bir fikir ?? ve ayrıca statik nesneyi tekli yöntemle tutmanın daha iyi bir yaklaşım olduğunu öneriyor ???

Yanıtlar:


239

Biraz arka planla başlayalım: Bir uygulamayı başlattığınızda ne olur?
İşletim sistemi bir işlemi başlatır ve ona benzersiz bir işlem kimliği atar ve bir işlem tablosu tahsis eder. Bir işlem bir DVM örneğini (Dalvik VM) başlatır; Her uygulama bir DVM içinde çalışır.
Bir DVM, sınıf yükleme boşaltma, örnek yaşam döngüsü, GC vb. Yönetir.

Statik bir değişkenin ömrü: Statik bir değişken, bir sınıf JVM tarafından yüklendiğinde ortaya çıkar ve sınıf kaldırıldığında ölür.

Dolayısıyla, bir android uygulaması oluşturur ve bir statik değişkeni başlatırsanız, aşağıdakilerden biri gerçekleşene kadar JVM'de kalacaktır:
1. sınıf kaldırılır
2. JVM kapanır
3. işlem ölür

Statik değişkenin değerinin, başka bir uygulamanın farklı bir etkinliğine geçtiğinizde devam edeceğini ve yukarıdaki üçünün hiçbirinin gerçekleşmeyeceğini unutmayın. Yukarıdaki üçten herhangi biri olursa statik değerini kaybeder.

Bunu birkaç satır kodla test edebilirsiniz:

  1. başlatılmamış durağı onCreate of your activity'de yazdır -> boş yazdırmalı
  2. Statiği başlat. print it -> değer boş olmayacaktır
  3. Geri düğmesine basın ve ana ekrana gidin. Not: Ana ekran başka bir etkinliktir.
  4. Aktivitenizi tekrar başlatın -> statik değişken boş olmayacaktır
  5. Başvuru sürecinizi DDMS'den sonlandırın (cihazlar penceresindeki durdur düğmesi).
  6. Aktivitenizi yeniden başlatın -> statik boş değere sahip olacaktır.

Umarım yardımcı olur.


1
Yeni aktiviteye başladığımda statik değilse, uygulama nesnesindeki alan değerimi neden kaybettiğimi bilmek istiyorum, örneğin uygulama nesnesinde değişken geçerli sayfa
bildiriyorum

super.onRestoreInstanceState (SavedInstanceState) 'i çağırdığımda; Değişkenimi statik de olsa kaybederim, sorun nedir?
Mohammed Subhi Sheikh Quroush

1
bu güzel bir açıklama (yani -1 yok) ama biraz önemsiz: OP açıkça "düşük bellek durumları" hakkında sorular sordu (burada olmamın nedeni), bildiğim kadarıyla işletim sistemi sanal makineyi öldürebilir ve daha sonra aynı parametrelerle yeniden başlatın ve bu durum ( eğer gerçekse) burada ele
alınmaz

1
@suitianshi Statik örnekleri Application.onCreate'de başlatabileceğimizi düşünüyorum, çünkü uygulamamız arka plana geçse ve süreç kapatılsa bile, uygulamamıza geri döndüğümüzde, Application sınıfı başlatılacak ve buna karşılık gelen yaşam döngüsü yöntemlerini çağıracak tekrar! bununla ilgili onaya ihtiyacım olmasına rağmen, Application.onCreate'de başlatılan statik örneğin değerini kaybettiği herhangi bir senaryo olabilir mi acaba?
Sarthak Mittal

1
Burada kaçırdığım şey "1. sınıf kaldırıldı" için bir açıklama - bu ne zaman olacak? JVM, bellek yetersizse bir sınıfı kaldırır mı?
stoefln

16

Eh, Singleton modeli de statik değişkenleri kullanmaya dayalıdır, bu yüzden aslında aynı konumda olursunuz. Statik yaklaşım çoğu zaman işe yarasa da, bazı durumlarda bellek dolu olduğunda ve uygulamanız bir sonraki ekrana geçmeden önce başka bir faaliyetin ön plana çıktığı durumlarda, etkinliğinizin süreci durdurulabilir ve statik değerleri kaybedebilirsiniz. Bununla birlikte, Android, durumlar arasında değerleri kalıcı hale getirmek veya bunları aşağıdaki gibi iletmek için birkaç seçenek sunar:

  • Bir Amaç kullanarak, arama kriterlerinizi etkinlikten etkinliğe aktarabilirsiniz (bir web http isteğine benzer şekilde)
  • uygulama tercihlerini kullanarak değerleri kaydedebilir ve ihtiyaç duyan aktivitede geri alabilirsiniz.
  • sqlite veritabanını kullanarak bunları bir tabloda kalıcı hale getirebilir ve daha sonra geri alabilirsiniz.
  • Yeniden başlatma sırasında alanların önceden seçilen değerleriyle doldurulması için etkinlik durumunu kaydetmeniz gerekiyorsa, onSaveInstanceState () etkinlik yöntemini uygulayabilirsiniz - bunun, durumların faaliyetler arasında kalıcılığı için önerilmediğini unutmayın.

Google kodundaki veya diğer açık kaynak Android uygulamalarındaki aegis-shield kaynak kod ağacına bakarak tercihlerin, amaçların ve sqlite veritabanının kullanımına ilişkin bazı kod örneklerini edinebilirsiniz .


6

Biraz araştırmadan sonra, uygulamayı yeniden oluşturmaya hazır olmadığınız sürece, tekilleri depolamak için Uygulama'yı kullanmanın o kadar da harika bir fikir olmadığı ortaya çıktı:

Verileri uygulama nesnesinde saklamayın

bu yüzden kabul edilen cevap teknik olarak doğru olsa da tüm bilgileri sağlamaz.

Yukarıdaki bağlantının önerdiği gibi, bu modele gerçekten bağlı kalmak istiyorsanız, boşluğu kontrol etmeye ve mümkünse verileri yeniden oluşturmaya hazır olmanız gerekir.


3

@ r1k0 tam burada. Verileri bir sınıfın statik alanlarında depolamak, uygulama süreci öldürür ve yeniden başlatır boyunca kendi başına kalmaz. Android, belleğe ihtiyaç duyduğunda rutin olarak işlemleri (çalışan uygulamaları) sonlandırır.

Android belgesine göre: Etkinlik durumu ve bellekten çıkarma ,

Sistem hiçbir zaman bir faaliyeti doğrudan öldürmez. Bunun yerine, aktivitenin işlediği süreci öldürür, sadece aktiviteyi değil, aynı zamanda süreçte çalışan diğer her şeyi de yok eder.

Aşağıdaki yöntemleri kullanarak ilkel nesnelerin yanı sıra Serileştirilebilir ve Ayrıştırılabilir nesnelerin durumunu kaydedebilir ve geri yükleyebilirsiniz. Bunlar, normal etkinlik yaşam döngüsü sırasında otomatik olarak çağrılır.

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

Dolayısıyla, yalnızca statik değişkenlere sahip bir sınıfınız varsa, her alanın durumunu onSaveInstanceState () 'de kaydedebilir ve bunları onRestoreInstanceState ()' de geri yükleyebilirsiniz. Android, uygulamanızın içinde çalıştığı işlemi bitirdiğinde, değişkenlerinizin durumu kaydedilir ve Android uygulamanızı geri yüklediğinde, değerler bellekte eskisi gibi aynı durumda geri yüklenir.

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.