Etkinlik yaşam döngüsü (Görünümler)

Kavramlar ve Jetpack Compose uygulaması

Kullanıcı uygulamanızda gezinirken, uygulamadan çıkarken ve uygulamaya geri dönerken uygulamanızdaki Activity örnekleri, yaşam döngülerinde farklı durumlara geçer. Activity sınıfı, etkinliğin bir durumun değiştiğini veya sistemin bir etkinliği oluşturduğunu, durdurduğunu ya da devam ettirdiğini veya etkinliğin bulunduğu işlemi yok ettiğini bilmesini sağlayan bir dizi geri çağırma sağlar.

Yaşam döngüsü geri çağırma yöntemlerinde, kullanıcı etkinliği terk edip yeniden girdiğinde etkinliğinizin nasıl davranacağını belirtebilirsiniz. Örneğin, bir akış video oynatıcı oluşturuyorsanız kullanıcı başka bir uygulamaya geçtiğinde videoyu duraklatabilir ve ağ bağlantısını sonlandırabilirsiniz. Kullanıcı geri döndüğünde ağa yeniden bağlanabilir ve kullanıcının videoyu aynı noktadan devam ettirmesine izin verebilirsiniz.

Her geri çağırma, belirli bir durum değişikliğine uygun özel bir çalışma yapmanıza olanak tanır. Doğru zamanda doğru işi yapmak ve geçişleri düzgün bir şekilde yönetmek, uygulamanızı daha sağlam ve performanslı hale getirir. Örneğin, yaşam döngüsü geri çağırmalarının iyi bir şekilde uygulanması, uygulamanızın aşağıdakilerden kaçınmasına yardımcı olabilir:

  • Kullanıcı, uygulamanızı kullanırken telefon araması aldığında veya başka bir uygulamaya geçtiğinde uygulamanın kilitlenmesi.
  • Kullanıcı etkin olarak kullanmadığı zaman değerli sistem kaynaklarını tüketir.
  • Kullanıcılar uygulamanızdan çıkıp daha sonra geri döndüğünde ilerlemelerini kaybetme
  • Ekran yatay ve dikey yön arasında döndürüldüğünde uygulamanın kilitlenmesi veya kullanıcının ilerleme durumunun kaybolması.

Bu belgede, etkinlik yaşam döngüsü ayrıntılı olarak açıklanmaktadır. Belge, yaşam döngüsü paradigmasını açıklayarak başlar. Ardından, geri çağırmaların her biri açıklanır: Bunlar yürütülürken dahili olarak neler olur ve bunlar sırasında neleri uygulamanız gerekir.

Ardından, etkinlik durumu ile bir sürecin sistem tarafından sonlandırılmaya karşı savunmasızlığı arasındaki ilişki kısaca açıklanır. Son olarak, etkinlik durumları arasındaki geçişlerle ilgili çeşitli konular ele alınır.

En iyi uygulamalarla ilgili yönergeler de dahil olmak üzere yaşam döngülerinin işlenmesi hakkında bilgi edinmek için Yaşam Döngüsüne Duyarlı Bileşenlerle Yaşam Döngülerini İşleme ve Kullanıcı arayüzü durumlarını kaydetme başlıklı makaleleri inceleyin. Etkinlikleri mimari bileşenlerle birlikte kullanarak sağlam ve üretim kalitesinde bir uygulama tasarlamayı öğrenmek için Uygulama mimarisi kılavuzu başlıklı makaleyi inceleyin.

Etkinlik yaşam döngüsü kavramları

Etkinlik yaşam döngüsünün aşamaları arasındaki geçişlerde gezinmek için Activity sınıfı, temel bir geri çağırma grubu sağlar: onCreate, onStart, onResume, onPause, onStop ve onDestroy. Sistem, etkinlik yeni bir duruma girdiğinde bu geri çağırmaların her birini çağırır.

Şekil 1'de bu paradigmanın görsel bir temsili sunulmaktadır.

Şekil 1. Etkinlik yaşam döngüsünün basitleştirilmiş bir resmi.

Kullanıcı etkinlikten ayrılmaya başladığında sistem, etkinliği kaldırmak için yöntemleri çağırır. Bazı durumlarda, etkinlik yalnızca kısmen kaldırılır ve kullanıcı başka bir uygulamaya geçtiğinde olduğu gibi bellekte kalmaya devam eder. Bu durumlarda etkinlik, ön plana geri gelebilir.

Kullanıcı etkinliğe geri dönerse etkinlik, kullanıcının kaldığı yerden devam eder. Birkaç istisna dışında, uygulamaların arka planda çalışırken etkinlik başlatması kısıtlanır.

Sistemin belirli bir işlemi ve içindeki etkinlikleri sonlandırma olasılığı, etkinliğin o sıradaki durumuna bağlıdır. Durum ile bellekten çıkarma hassasiyeti arasındaki ilişki hakkında daha fazla bilgi için Etkinlik durumu ve bellekten çıkarma bölümüne bakın.

Etkinliğinizin karmaşıklığına bağlı olarak, yaşam döngüsü yöntemlerinin tümünü uygulamanız gerekmeyebilir. Ancak her birini anlamanız ve uygulamanız önemlidir. Bu sayede uygulamanız, kullanıcıların beklediği şekilde çalışır.

Yaşam döngüsü geri çağırmaları

Bu bölümde, etkinlik yaşam döngüsü sırasında kullanılan geri çağırma yöntemleri hakkında kavramsal ve uygulama bilgileri verilmektedir.

Bazı işlemler etkinlik yaşam döngüsü yöntemlerine aittir. Ancak bağımlı bir bileşenin işlemlerini uygulayan kodu, etkinlik yaşam döngüsü yöntemi yerine bileşene yerleştirin. Bunu yapmak için bağımlı bileşenin yaşam döngüsünden haberdar olması gerekir. Bağımlı bileşenlerinizi yaşam döngüsüne duyarlı hale getirme hakkında bilgi edinmek için Yaşam döngüsüne duyarlı bileşenlerle yaşam döngülerini işleme başlıklı makaleyi inceleyin.

onCreate

Sistem etkinliği ilk kez oluşturduğunda tetiklenen bu geri çağırmayı uygulamanız gerekir. Etkinlik oluşturulduğunda Oluşturuldu durumuna geçer. onCreate yönteminde, etkinliğin tüm yaşamı boyunca yalnızca bir kez gerçekleşen temel uygulama başlatma mantığını uygulayın.

Örneğin, onCreate öğesini uyguladığınızda veriler listelere bağlanabilir, etkinlik bir ViewModel ile ilişkilendirilebilir ve bazı sınıf kapsamlı değişkenler oluşturulabilir. Bu yöntem, etkinliğin daha önce kaydedilmiş durumunu içeren bir Bundle nesnesi olan savedInstanceState parametresini alır. Etkinlik daha önce hiç yoksa Bundle nesnesinin değeri null olur.

Etkinliğinizin yaşam döngüsüne bağlı, yaşam döngüsünden haberdar bir bileşeniniz varsa ON_CREATE etkinliğini alır. @OnLifecycleEvent ile açıklama eklenmiş yöntem, yaşam döngüsünden haberdar bileşeninizin oluşturulan durum için ihtiyaç duyduğu kurulum kodunu çalıştırabilmesi amacıyla çağrılır.

onCreate yönteminin aşağıdaki örneğinde, kullanıcı arayüzünü (XML düzen dosyasında tanımlanır) bildirme, üye değişkenlerini tanımlama ve kullanıcı arayüzünün bir kısmını yapılandırma gibi etkinliğin temel kurulumu gösterilmektedir. Bu örnekte, XML düzen dosyası, dosyanın kaynak kimliğini R.layout.main_activity, setContentView öğesine iletir.

Kotlin

lateinit var textView: TextView

// Some transient state for the activity instance.
var gameState: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
    // Call the superclass onCreate to complete the creation of
    // the activity, like the view hierarchy.
    super.onCreate(savedInstanceState)

    // Recover the instance state.
    gameState = savedInstanceState?.getString(GAME_STATE_KEY)

    // Set the user interface layout for this activity.
    // The layout is defined in the project res/layout/main_activity.xml file.
    setContentView(R.layout.main_activity)

    // Initialize member TextView so it is available later.
    textView = findViewById(R.id.text_view)
}

// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY)
}

// Invoked when the activity might be temporarily destroyed; save the instance state here.
override fun onSaveInstanceState(outState: Bundle?) {
    outState?.run {
        putString(GAME_STATE_KEY, gameState)
        putString(TEXT_VIEW_KEY, textView.text.toString())
    }
    // Call superclass to save any view hierarchy.
    super.onSaveInstanceState(outState)
}

Java

TextView textView;
// Some transient state for the activity instance.
String gameState;

@Override
public void onCreate(Bundle savedInstanceState) {
    // Call the superclass onCreate to complete the creation of
    // the activity, like the view hierarchy.
    super.onCreate(savedInstanceState);

    // Recover the instance state.
    if (savedInstanceState != null) {
        gameState = savedInstanceState.getString(GAME_STATE_KEY);
    }

    // Set the user interface layout for this activity.
    // The layout is defined in the project res/layout/main_activity.xml file.
    setContentView(R.layout.main_activity);

    // Initialize member TextView so it is available later.
    textView = (TextView) findViewById(R.id.text_view);
}

// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}

// Invoked when the activity might be temporarily destroyed; save the instance state here.
@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putString(GAME_STATE_KEY, gameState);
    outState.putString(TEXT_VIEW_KEY, textView.getText());

    // Call superclass to save any view hierarchy.
    super.onSaveInstanceState(outState);
}

XML dosyasını tanımlayıp setContentView'ye iletmek yerine, etkinlik kodunuzda yeni View nesneleri oluşturabilir ve yeni View nesnelerini ViewGroup içine yerleştirerek bir görünüm hiyerarşisi oluşturabilirsiniz. Ardından, kök ViewGroup öğesini setContentView öğesine ileterek bu düzeni kullanırsınız. Kullanıcı arayüzü oluşturma hakkında daha fazla bilgi için kullanıcı arayüzü dokümanlarına bakın.

Etkinliğiniz Oluşturuldu durumunda kalmaz. onCreate yöntemi yürütmeyi tamamladıktan sonra etkinlik Başlatıldı durumuna girer ve sistem, onStart ve onResume yöntemlerini hızlı bir şekilde çağırır.

onStart

Etkinlik Başlatıldı durumuna girdiğinde sistem onStart işlevini çağırır. Bu çağrı, uygulama etkinliğin ön plana çıkıp etkileşimli hale gelmesine hazırlanırken etkinliği kullanıcıya görünür kılar. Örneğin, bu yöntemde kullanıcı arayüzünü koruyan kod başlatılır.

Etkinlik Başlatıldı durumuna geçtiğinde, etkinliğin yaşam döngüsüne bağlı tüm yaşam döngüsü farkında bileşenler ON_START etkinliğini alır.

onStart yöntemi hızlı bir şekilde tamamlanır ve oluşturuldu durumunda olduğu gibi etkinlik başlatıldı durumunda kalmaz. Bu geri çağırma işlemi tamamlandığında etkinlik Resumed durumuna girer ve sistem onResume yöntemini çağırır.

onResume

Etkinlik Devam Ediyor durumuna girdiğinde ön plana gelir ve sistem onResume geri çağırmasını başlatır. Bu, uygulamanın kullanıcıyla etkileşim kurduğu durumdur. Uygulama, odak noktasını uygulamadan uzaklaştıran bir olay (ör. cihazın telefon araması alması, kullanıcının başka bir etkinliğe gitmesi veya cihaz ekranının kapanması) gerçekleşene kadar bu durumda kalır.

Etkinlik, Devam Edildi durumuna geçtiğinde etkinliğin yaşam döngüsüne bağlı olan yaşam döngüsü farkında tüm bileşenler ON_RESUME etkinliğini alır. Yaşam döngüsü bileşenleri, bileşen görünür ve ön plandayken çalışması gereken tüm işlevleri (ör. kamera önizlemesini başlatma) etkinleştirebilir.

Kesintiye neden olan bir etkinlik gerçekleştiğinde etkinlik Duraklatıldı durumuna girer ve sistem onPause geri çağırmasını başlatır.

Etkinlik, Duraklatıldı durumundan Devam Ediyor durumuna dönerse sistem onResume yöntemini tekrar çağırır. Bu nedenle, onResume'ı uygulayarak onPause sırasında yayınladığınız bileşenleri başlatın ve etkinlik her Resumed durumuna girdiğinde yapılması gereken diğer tüm başlatma işlemlerini gerçekleştirin.

Aşağıda, bileşen ON_RESUME etkinliğini aldığında kameraya erişen yaşam döngüsü farkında bir bileşene örnek verilmiştir:

Kotlin

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun initializeCamera() {
        if (camera == null) {
            getCamera()
        }
    }
    ...
}

Java

public class CameraComponent implements LifecycleObserver {

    ...

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void initializeCamera() {
        if (camera == null) {
            getCamera();
        }
    }
    ...
}

Yukarıdaki kod, LifecycleObserver, ON_RESUME etkinliğini aldığında kamerayı başlatır. Ancak çoklu pencere modunda, etkinliğiniz Duraklatıldı durumunda olsa bile tamamen görünür olabilir. Örneğin, uygulama çok pencereli moddayken ve kullanıcı etkinliğinizi içermeyen pencereye dokunduğunda etkinliğiniz Duraklatıldı durumuna geçer.

Kameranın yalnızca uygulama devam ettirildiğinde (görünür ve ön planda etkin) etkin olmasını istiyorsanız kamerayı daha önce gösterilen ON_RESUME etkinliğinden sonra başlatın. Etkinlik Duraklatılmışken ancak görünür durumdayken (ör. çoklu pencere modunda) kamerayı etkin tutmak istiyorsanız kamerayı ON_START etkinliğinden sonra başlatın.

Ancak etkinliğiniz Duraklatılmış durumdayken kameranın etkin olması, çoklu pencere modunda başka bir Devam Ettirilen uygulamanın kameraya erişmesini engelleyebilir. Bazen etkinliğiniz duraklatılmışken kamerayı etkin tutmanız gerekebilir ancak bunu yaparsanız genel kullanıcı deneyimi kötüleşebilir.

Bu nedenle, çok pencereli mod bağlamında paylaşılan sistem kaynaklarının kontrolünü yaşam döngüsünün hangi aşamasında almanın en uygun olacağını dikkatlice düşünün. Çoklu pencere modunu destekleme hakkında daha fazla bilgi edinmek için Çoklu pencere modunu destekleme başlıklı makaleyi inceleyin.

Hangi hazırlık etkinliğinde başlatma işlemi yapmayı seçerseniz seçin, kaynağı serbest bırakmak için ilgili yaşam döngüsü olayı kullandığınızdan emin olun. ON_START etkinliğinden sonra bir şeyi başlatırsanız ON_STOP etkinliğinden sonra yayınlayın veya sonlandırın. ON_RESUME etkinliğinden sonra başlatırsanız ON_PAUSE etkinliğinden sonra serbest bırakın.

Yukarıdaki kod snippet'i, kamera başlatma kodunu yaşam döngüsünden haberdar bir bileşene yerleştirir. Bunun yerine bu kodu doğrudan onStart ve onStop gibi etkinlik yaşam döngüsü geri çağırma yöntemlerine yerleştirebilirsiniz ancak bunu önermiyoruz. Bu mantığı bağımsız ve yaşam döngüsüne duyarlı bir bileşene ekleyerek kodu çoğaltmak zorunda kalmadan bileşeni birden fazla etkinlikte yeniden kullanabilirsiniz. Yaşam döngüsüne duyarlı bileşen oluşturmayı öğrenmek için Yaşam döngüsüne duyarlı bileşenlerle (Görünümler) yaşam döngülerini işleme başlıklı makaleye bakın.

onPause

Sistem, bu yöntemi kullanıcının etkinliğinizden ayrıldığına dair ilk gösterge olarak çağırır ancak bu, etkinliğin her zaman yok edildiği anlamına gelmez. Bu, etkinliğin artık ön planda olmadığını ancak kullanıcı çok pencereli moddaysa hala görünür olduğunu gösterir. Bir etkinliğin bu duruma girmesinin çeşitli nedenleri olabilir:

  • onResume geri çağırma bölümünde açıklandığı gibi, uygulama yürütmesini kesintiye uğratan bir etkinlik, mevcut etkinliği duraklatır. Bu, en yaygın durumdur.
  • Çoklu pencere modunda, herhangi bir zamanda yalnızca bir uygulama odaklanabilir ve sistem diğer tüm uygulamaları duraklatır.
  • İletişim kutusu gibi yeni ve yarı şeffaf bir etkinliğin açılması, kapsadığı etkinliği duraklatır. Etkinlik kısmen görünür olduğu ancak ön planda olmadığı sürece duraklatılmış olarak kalır.

Bir etkinlik Duraklatıldı durumuna geçtiğinde, etkinliğin yaşam döngüsüne bağlı olan yaşam döngüsü farkında tüm bileşenler ON_PAUSE etkinliğini alır. Yaşam döngüsü bileşenleri, bileşen ön planda değilken çalışması gerekmeyen işlevleri (ör. kamera önizlemesini durdurma) burada durdurabilir.

Activity Duraklatılmış durumdayken devam edemeyen veya ılımlı bir şekilde devam edebilecek ve kısa süre içinde devam etmesini beklediğiniz işlemleri duraklatmak ya da ayarlamak için onPause yöntemini kullanın.

Ayrıca, etkinliğiniz duraklatılmışken ve kullanıcının bunlara ihtiyacı yokken sistem kaynaklarını, sensörlere (ör. GPS) yönelik tutamaçları veya pil ömrünü etkileyen kaynakları serbest bırakmak için onPause yöntemini de kullanabilirsiniz.

Ancak onResume ile ilgili bölümde belirtildiği gibi, uygulama çok pencereli moddaysa duraklatılmış bir etkinlik yine de tamamen görünür olabilir. Kullanıcı arayüzüyle ilgili kaynakları ve işlemleri çoklu pencere modunu daha iyi destekleyecek şekilde tamamen yayınlamak veya ayarlamak için onPause yerine onStop kullanmayı düşünebilirsiniz.

Aşağıdaki ON_PAUSE etkinliğine tepki veren LifecycleObserver örneği, önceki ON_RESUME etkinlik örneğinin karşılığıdır ve ON_RESUME etkinliği alındıktan sonra başlatılan kamerayı serbest bırakır:

Kotlin

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun releaseCamera() {
        camera?.release()
        camera = null
    }
    ...
}

Java

public class JavaCameraComponent implements LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void releaseCamera() {
        if (camera != null) {
            camera.release();
            camera = null;
        }
    }
    ...
}

Bu örnekte, kamera yayın kodu ON_PAUSE etkinliği LifecycleObserver tarafından alındıktan sonra yerleştirilir.

onPause yürütme işlemi çok kısa sürer ve kaydetme işlemlerini gerçekleştirmek için yeterli zamanı sunmayabilir. Bu nedenle, uygulama veya kullanıcı verilerini kaydetmek, ağ çağrıları yapmak ya da veritabanı işlemleri yürütmek için onPause kullanmayın. Bu tür çalışmalar, yöntem tamamlanmadan önce tamamlanmayabilir.

Bunun yerine, ağır yük kapatma işlemlerini onStop sırasında gerçekleştirin. onStop sırasında gerçekleştirilebilecek uygun işlemler hakkında daha fazla bilgi için sonraki bölüme bakın. Verileri kaydetme hakkında daha fazla bilgi için durumu kaydetme ve geri yükleme bölümüne bakın.

onPause yönteminin tamamlanması, etkinliğin Duraklatıldı durumundan çıktığı anlamına gelmez. Bunun yerine, etkinlik devam edene veya kullanıcı için tamamen görünmez hale gelene kadar bu durumda kalır. Etkinlik devam ederse sistem onResume geri çağırma işlevini tekrar çağırır.

Etkinlik Duraklatıldı durumundan Devam Ediyor durumuna dönerse sistem, Activity örneğini bellekte tutar ve sistem onResume öğesini çağırdığında bu örneği geri çağırır. Bu senaryoda, Devam Edildi durumuna kadar olan geri çağırma yöntemleri sırasında oluşturulan bileşenleri yeniden başlatmanız gerekmez. Etkinlik tamamen görünmez hale gelirse sistem onStop işlevini çağırır.

onStop

Etkinliğiniz kullanıcı tarafından artık görünmediğinde Durduruldu durumuna geçer ve sistem onStop geri çağırmasını başlatır. Bu durum, yeni başlatılan bir etkinlik ekranın tamamını kapladığında meydana gelebilir. Sistem, etkinlik çalışmayı bitirip sonlandırılmak üzereyken de onStop işlevini çağırır.

Etkinlik Durduruldu durumuna geçtiğinde, etkinliğin yaşam döngüsüne bağlı yaşam döngüsü farkında olan tüm bileşenler ON_STOP etkinliğini alır. Yaşam döngüsü bileşenleri, bileşen ekranda görünmüyorken çalışması gerekmeyen işlevleri burada durdurabilir.

onStop yönteminde, uygulama kullanıcıya görünmüyorken ihtiyaç duyulmayan kaynakları serbest bırakın veya ayarlayın. Örneğin, uygulamanız animasyonları duraklatabilir veya ayrıntılı konum güncellemelerinden genel konum güncellemelerine geçebilir. onPause yerine onStop kullanmak, kullanıcı etkinliğinizi çok pencereli modda görüntülerken bile kullanıcı arayüzüyle ilgili çalışmaların devam etmesini sağlar.

Ayrıca, nispeten CPU yoğun kapatma işlemleri gerçekleştirmek için onStop kullanın. Örneğin, bilgileri veritabanına kaydetmek için daha iyi bir zaman bulamıyorsanız bunu onStop sırasında yapabilirsiniz. Aşağıdaki örnekte, taslak notun içeriğini kalıcı depolama alanına kaydeden bir onStop uygulaması gösterilmektedir:

Kotlin

override fun onStop() {
    // Call the superclass method first.
    super.onStop()

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    val values = ContentValues().apply {
        put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText())
        put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle())
    }

    // Do this update in background on an AsyncQueryHandler or equivalent.
    asyncQueryHandler.startUpdate(
            token,     // int token to correlate calls
            null,      // cookie, not used here
            uri,       // The URI for the note to update.
            values,    // The map of column names and new values to apply to them.
            null,      // No SELECT criteria are used.
            null       // No WHERE columns are used.
    )
}

Java

@Override
protected void onStop() {
    // Call the superclass method first.
    super.onStop();

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    // Do this update in background on an AsyncQueryHandler or equivalent.
    asyncQueryHandler.startUpdate (
            mToken,  // int token to correlate calls
            null,    // cookie, not used here
            uri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
    );
}

Yukarıdaki kod örneğinde doğrudan SQLite kullanılıyor. Ancak, SQLite üzerinde bir soyutlama katmanı sağlayan bir kalıcılık kitaplığı olan Room'u kullanmanızı öneririz. Room kullanmanın avantajları ve Room'u uygulamanıza nasıl entegre edeceğiniz hakkında daha fazla bilgi edinmek için Room kalıcılık kitaplığı kılavuzuna bakın.

Etkinliğiniz Durduruldu durumuna girdiğinde Activity nesnesi bellekte kalır: Tüm durum ve üye bilgilerini korur ancak pencere yöneticisine bağlı değildir. Etkinlik devam ettiğinde bu bilgiler hatırlanır.

Devam Edildi durumuna kadar olan geri çağırma yöntemleri sırasında oluşturulan bileşenleri yeniden başlatmanız gerekmez. Sistem, düzendeki her View nesnenin mevcut durumunu da takip eder. Bu nedenle, kullanıcı bir EditText widget'ına metin girerse bu içerik korunur. Böylece, içeriği kaydetmeniz ve geri yüklemeniz gerekmez.

Durduruldu durumunda etkinlik, kullanıcıyla etkileşim kurmak için geri döner veya etkinlik çalışmayı tamamlayıp kaybolur. Etkinlik geri gelirse sistem onRestart işlevini çağırır. Activity çalışması tamamlandığında sistem onDestroy'ı çağırır.

onDestroy

onDestroy, etkinlik yok edilmeden önce çağrılır. Sistem, bu geri çağırmayı iki nedenden biriyle çağırır:

  1. Kullanıcı etkinliği tamamen kapattığı veya etkinlikte finish çağrıldığı için etkinlik sona eriyor.
  2. Sistem, yapılandırma değişikliği (ör. cihazı döndürme veya çok pencereli moda girme) nedeniyle etkinliği geçici olarak yok ediyor.

Etkinlik yok edildi durumuna geçtiğinde, etkinliğin yaşam döngüsüne bağlı yaşam döngüsünden haberdar tüm bileşenler ON_DESTROY etkinliğini alır. Yaşam döngüsü bileşenleri, Activity yok edilmeden önce temizlemeleri gereken her şeyi burada temizleyebilir.

Activity öğenizin neden yok edildiğini belirlemek için mantık yerleştirmek yerine, Activity öğenizle ilgili görünüm verilerini içeren bir ViewModel nesnesi kullanın. Activity, yapılandırma değişikliği nedeniyle yeniden oluşturulursa ViewModel korunup sonraki Activity örneğine verildiğinden herhangi bir işlem yapması gerekmez.

Activity yeniden oluşturulmazsa ViewModel, yok edilmeden önce temizlemesi gereken verileri temizleyebileceği onCleared yöntemini çağırır. isFinishing yöntemiyle bu iki senaryo arasında ayrım yapabilirsiniz.

Etkinlik sona eriyorsa onDestroy, etkinliğin aldığı son yaşam döngüsü geri çağırma yöntemidir. onDestroy bir yapılandırma değişikliği sonucunda çağrılırsa sistem hemen yeni bir etkinlik örneği oluşturur ve ardından yeni yapılandırmadaki bu yeni örnekte onCreate'ı çağırır.

onDestroy geri çağırma işlevi, onStop gibi önceki geri çağırma işlevleri tarafından serbest bırakılmayan tüm kaynakları serbest bırakır.

Geçici kullanıcı arayüzü durumunu kaydetme ve geri yükleme

Kullanıcılar, döndürme veya çok pencereli moda geçme gibi yapılandırma değişiklikleri sırasında etkinliklerin kullanıcı arayüzü durumunun aynı kalmasını bekler. Ancak sistem, bu tür bir yapılandırma değişikliği gerçekleştiğinde etkinliği varsayılan olarak yok eder ve etkinlik örneğinde depolanan tüm kullanıcı arayüzü durumunu siler.

Benzer şekilde, kullanıcılar uygulamanızdan geçici olarak başka bir uygulamaya geçip daha sonra uygulamanıza geri döndüklerinde kullanıcı arayüzü durumunun aynı kalmasını bekler. Ancak kullanıcı uzaktayken ve etkinliğiniz durdurulmuşken sistem, uygulamanızın sürecini sonlandırabilir.

Sistem kısıtlamaları etkinliği kaldırdığında ViewModel, onSaveInstanceState ve/veya yerel depolama alanı kullanarak kullanıcının geçici kullanıcı arayüzü durumunu koruyun. Kullanıcı beklentileri ile sistem davranışları arasındaki fark ve sistem tarafından başlatılan etkinlik ile süreç sonlandırma sırasında karmaşık kullanıcı arayüzü durumu verilerini en iyi şekilde nasıl koruyacağınız hakkında daha fazla bilgi edinmek için Kullanıcı arayüzü durumlarını kaydetme başlıklı makaleyi inceleyin.

Bu bölümde, örnek durumun ne olduğu ve etkinliğin kendisinde geri çağırma olan onSaveInstance yönteminin nasıl uygulanacağı açıklanmaktadır. Kullanıcı arayüzü verileriniz hafifse kullanıcı arayüzü durumunu hem yapılandırma değişiklikleri hem de sistem tarafından başlatılan işlem sonlandırma boyunca kalıcı hale getirmek için yalnızca onSaveInstance kullanabilirsiniz. Ancak onSaveInstance, serileştirme/serileştirmeyi kaldırma maliyetlerine neden olduğundan çoğu durumda Kullanıcı arayüzü durumlarını kaydetme bölümünde belirtildiği gibi hem ViewModel hem de onSaveInstance kullanılır.

Yapılandırma değişikliklerini işleme sayfasını inceleyin.

Örnek durumu

Etkinliğinizin normal uygulama davranışı nedeniyle yok edildiği birkaç senaryo vardır. Örneğin, kullanıcı Geri düğmesine bastığında veya etkinliğiniz finish yöntemini çağırarak kendi yok edilmesini işaret ettiğinde.

Kullanıcı Geri düğmesine bastığında veya etkinlik kendi kendine tamamlandığında etkinliğiniz yok edildiği için hem sistemin hem de kullanıcının Activity örneğiyle ilgili kavramı kalıcı olarak kaybolur. Bu senaryolarda kullanıcının beklentisi sistemin davranışı ile eşleşir ve sizin yapmanız gereken ek bir işlem olmaz.

Ancak sistem, sistem kısıtlamaları (ör. yapılandırma değişikliği veya bellek baskısı) nedeniyle etkinliği yok ederse gerçek Activity örneği kaybolur ancak sistem, bu örneğin var olduğunu hatırlar. Kullanıcı etkinliğe geri dönmeye çalıştığında sistem, etkinliğin yok edildiği sıradaki durumunu açıklayan bir dizi kayıtlı veriyi kullanarak etkinliğin yeni bir örneğini oluşturur.

Sistemin önceki durumu geri yüklemek için kullandığı kaydedilmiş verilere örnek durumu adı verilir. Bundle nesnesinde depolanan anahtar/değer çiftlerinden oluşan bir koleksiyondur. Sistem, varsayılan olarak EditText widget'ına girilen metin değeri gibi etkinlik düzeninizdeki her View nesnesiyle ilgili bilgileri kaydetmek için Bundleörnek durumunu kullanır.

Bu nedenle, etkinlik örneğiniz yok edilip yeniden oluşturulursa düzenin durumu, sizden herhangi bir kod girmeniz istenmeden önceki durumuna geri yüklenir. Ancak etkinliğinizde, kullanıcının etkinlikteki ilerleme durumunu izleyen üye değişkenleri gibi geri yüklemek isteyebileceğiniz daha fazla durum bilgisi olabilir.

Bundle nesnesi, ana iş parçacığında serileştirme gerektirdiğinden ve sistem süreci belleğini kullandığından önemsiz miktardan fazla veriyi korumak için uygun değildir. Çok küçük bir veri miktarından fazlasını korumak için Kullanıcı arayüzü durumlarını kaydetme bölümünde açıklandığı gibi, kalıcı yerel depolama, onSaveInstanceState yöntemi ve ViewModel sınıfını kullanarak verileri korumaya yönelik birleşik bir yaklaşım benimseyin.

onSaveInstanceState kullanarak basit ve hafif kullanıcı arayüzü durumunu kaydetme

Etkinliğiniz durdurulmaya başlandığında sistem, onSaveInstanceState yöntemini çağırır. Böylece etkinliğiniz durum bilgilerini bir örnek durum paketine kaydedebilir. Bu yöntemin varsayılan uygulaması, etkinliğin görünüm hiyerarşisinin durumuyla ilgili geçici bilgileri (ör. EditText widget'ındaki metin veya ListView widget'ının kaydırma konumu) kaydeder.

Etkinliğiniz için ek örnek durumu bilgileri kaydetmek üzere onSaveInstanceState işlevini geçersiz kılın ve etkinliğiniz beklenmedik bir şekilde yok edilirse kaydedilen Bundle nesnesine anahtar/değer çiftleri ekleyin. onSaveInstanceState geçersiz kıldığınızda, görünüm hiyerarşisinin durumunu kaydetmek için varsayılan uygulamayı kullanmak istiyorsanız üst sınıf uygulamasını çağırmanız gerekir. Bu durum aşağıdaki örnekte gösterilmektedir:

Kotlin

override fun onSaveInstanceState(outState: Bundle?) {
    // Save the user's current game state.
    outState?.run {
        putInt(STATE_SCORE, currentScore)
        putInt(STATE_LEVEL, currentLevel)
    }

    // Always call the superclass so it can save the view hierarchy state.
    super.onSaveInstanceState(outState)
}

companion object {
    val STATE_SCORE = "playerScore"
    val STATE_LEVEL = "playerLevel"
}

Java

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
// ...

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state.
    savedInstanceState.putInt(STATE_SCORE, currentScore);
    savedInstanceState.putInt(STATE_LEVEL, currentLevel);

    // Always call the superclass so it can save the view hierarchy state.
    super.onSaveInstanceState(savedInstanceState);
}

Kullanıcı tercihleri veya veritabanı verileri gibi kalıcı verileri kaydetmek için etkinliğiniz ön plandayken uygun fırsatları değerlendirin. Böyle bir fırsat oluşmazsa kalıcı verileri onStop yöntemi sırasında kaydedin.

Kayıtlı örnek durumunu kullanarak etkinlik kullanıcı arayüzü durumunu geri yükleme

Etkinliğiniz daha önce yok edildikten sonra yeniden oluşturulduğunda, sistemin etkinliğinize ilettiği Bundle'den kayıtlı örnek durumunuzu kurtarabilirsiniz. Hem onCreate hem de onRestoreInstanceState geri çağırma yöntemleri, örnek durumu bilgilerini içeren aynı Bundle değerini alır.

onCreate yöntemi, sistem etkinliğinizin yeni bir örneğini oluştururken veya önceki bir örneği yeniden oluştururken çağrıldığından, durumu okumaya çalışmadan önce Bundle durumunun null olup olmadığını kontrol etmeniz gerekir. Bu değer null ise sistem, yok edilen önceki bir etkinliği geri yüklemek yerine etkinliğin yeni bir örneğini oluşturur.

Aşağıdaki kod snippet'inde, onCreate içinde bazı durum verilerini nasıl geri yükleyebileceğiniz gösterilmektedir:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState) // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance.
    if (savedInstanceState != null) {
        with(savedInstanceState) {
            // Restore value of members from saved state.
            currentScore = getInt(STATE_SCORE)
            currentLevel = getInt(STATE_LEVEL)
        }
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance.
    if (savedInstanceState != null) {
        // Restore value of members from saved state.
        currentScore = savedInstanceState.getInt(STATE_SCORE);
        currentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

onCreate sırasında durumu geri yüklemek yerine, onRestoreInstanceState yönteminden sonra sistemin çağırdığı onStart yöntemini uygulayabilirsiniz. Sistem, yalnızca geri yüklenecek kayıtlı bir durum varsa onRestoreInstanceState işlevini çağırır. Bu nedenle, Bundle değerinin null olup olmadığını kontrol etmeniz gerekmez.

Kotlin

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    // Always call the superclass so it can restore the view hierarchy.
    super.onRestoreInstanceState(savedInstanceState)

    // Restore state members from saved instance.
    savedInstanceState?.run {
        currentScore = getInt(STATE_SCORE)
        currentLevel = getInt(STATE_LEVEL)
    }
}

Java

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy.
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance.
    currentScore = savedInstanceState.getInt(STATE_SCORE);
    currentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

Bir uygulama, kullanım ömrü boyunca etkinliğe girip çıkabilir. Örneğin, kullanıcı cihazın geri düğmesine dokunduğunda veya etkinlik farklı bir etkinlik başlattığında bu durum birçok kez yaşanabilir.

Bu bölümde, başarılı etkinlik geçişleri uygulamak için bilmeniz gereken konular ele alınmaktadır. Bu konular arasında başka bir etkinlikten etkinlik başlatma, etkinlik durumunu kaydetme ve etkinlik durumunu geri yükleme yer alır.

Bir etkinlikten başka bir etkinlik başlatma

Bir etkinliğin, belirli bir noktada başka bir etkinliği başlatması gerekebilir. Bu ihtiyaç, örneğin bir uygulamanın mevcut ekrandan yeni bir ekrana geçmesi gerektiğinde ortaya çıkar.

Etkinliğinizin, başlatmak üzere olduğu yeni etkinlikten sonuç alıp almayacağına bağlı olarak yeni etkinliği startActivity veya startActivityForResult yöntemini kullanarak başlatırsınız. Her iki durumda da Intent nesnesi iletirsiniz.

Intent nesnesi, başlatmak istediğiniz etkinliği tam olarak belirtir veya gerçekleştirmek istediğiniz işlem türünü açıklar. Sistem, sizin için uygun olan etkinliği seçer. Bu etkinlik farklı bir uygulamadan da olabilir. Intent nesnesi, başlatılan etkinlik tarafından kullanılacak küçük miktarlarda veri de taşıyabilir. Intent sınıfı hakkında daha fazla bilgi için Amaçlar ve Amaç Filtreleri başlıklı makaleyi inceleyin.

startActivity

Yeni başlatılan etkinliğin sonuç döndürmesi gerekmiyorsa mevcut etkinlik, startActivity yöntemini çağırarak etkinliği başlatabilir.

Kendi uygulamanızda çalışırken genellikle bilinen bir etkinliği başlatmanız yeterlidir. Örneğin, aşağıdaki kod snippet'inde SignInActivity adlı bir etkinliğin nasıl başlatılacağı gösterilmektedir.

Kotlin

val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)

Java

Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);

Uygulamanız, etkinliğinizdeki verileri kullanarak e-posta, kısa mesaj veya durum güncellemesi gönderme gibi bazı işlemler de gerçekleştirebilir. Bu durumda, uygulamanızın bu tür işlemleri gerçekleştirecek kendi etkinlikleri olmayabilir. Bu nedenle, cihazdaki diğer uygulamalar tarafından sağlanan ve işlemleri sizin için gerçekleştirebilecek etkinliklerden yararlanabilirsiniz.

Burada amaçlar gerçekten değerlidir. Yapmak istediğiniz işlemi açıklayan bir amaç oluşturabilirsiniz. Sistem, başka bir uygulamadan uygun etkinliği başlatır. Amacı işleyebilecek birden fazla etkinlik varsa kullanıcı hangisini kullanacağını seçebilir. Örneğin, kullanıcının e-posta iletisi göndermesine izin vermek istiyorsanız aşağıdaki amacı oluşturabilirsiniz:

Kotlin

val intent = Intent(Intent.ACTION_SEND).apply {
    putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)

Java

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

Amaca eklenen EXTRA_EMAIL, e-postanın gönderileceği e-posta adreslerinin dize dizisidir. Bir e-posta uygulaması bu amaca yanıt verdiğinde, ekstrada sağlanan dize dizisini okur ve adresleri e-posta oluşturma formunun "Alıcı" alanına yerleştirir. Bu durumda, e-posta uygulamasının etkinliği başlar ve kullanıcı işini bitirdiğinde etkinliğiniz devam eder.

startActivityForResult

Bazen bir etkinlik sona erdiğinde sonuç almak isteyebilirsiniz. Örneğin, kullanıcının bir kişi listesinden seçim yapmasına olanak tanıyan bir etkinlik başlatabilirsiniz. İşlem sona erdiğinde seçilen kişiyi döndürür. Bunu yapmak için startActivityForResult(Intent, int) yöntemini çağırırsınız. Burada tam sayı parametresi, aramayı tanımlar.

Bu tanımlayıcı, aynı etkinlikten startActivityForResult(Intent, int) için yapılan birden fazla çağrıyı ayırt etmek amacıyla kullanılır. Bu kimlik, genel bir tanımlayıcı değildir ve diğer uygulamalarla veya etkinliklerle çakışma riski yoktur. Sonuç, onActivityResult(int, int, Intent) yöntemiyle geri gelir.

Bir alt etkinlik sonlandırıldığında, verileri üst öğesine döndürmek için setResult(int) çağrılabilir. Alt etkinlik, standart sonuçlar RESULT_CANCELED, RESULT_OK veya RESULT_FIRST_USER ile başlayan özel değerler olabilen bir sonuç kodu sağlamalıdır.

Ayrıca, çocuk etkinliği isteğe bağlı olarak istediği ek verileri içeren bir Intent nesnesi döndürebilir. Üst etkinlik, bilgileri almak için onActivityResult(int, int, Intent) yöntemini ve üst etkinliğin başlangıçta sağladığı tam sayı tanımlayıcıyı kullanır.

Çocuk etkinliği, kilitlenme gibi herhangi bir nedenle başarısız olursa üst etkinlik RESULT_CANCELED koduyla bir sonuç alır.

Kotlin

class MyActivity : Activity() {
    // ...

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // When the user center presses, let them pick a contact.
            startActivityForResult(
                    Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")),
                    PICK_CONTACT_REQUEST)
            return true
        }
        return false
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        when (requestCode) {
            PICK_CONTACT_REQUEST ->
                if (resultCode == RESULT_OK) {
                    // A contact was picked. Display it to the user.
                    startActivity(Intent(Intent.ACTION_VIEW, intent?.data))
                }
        }
    }

    companion object {
        internal val PICK_CONTACT_REQUEST = 0
    }
}

Java

public class MyActivity extends Activity {
    // ...

    static final int PICK_CONTACT_REQUEST = 0;

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // When the user center presses, let them pick a contact.
            startActivityForResult(
                new Intent(Intent.ACTION_PICK,
                new Uri("content://contacts")),
                PICK_CONTACT_REQUEST);
            return true;
        }
        return false;
    }

    protected void onActivityResult(int requestCode, int resultCode,
            Intent data) {
        if (requestCode == PICK_CONTACT_REQUEST) {
            if (resultCode == RESULT_OK) {
                // A contact was picked. Display it to the user.
                startActivity(new Intent(Intent.ACTION_VIEW, data));
            }
        }
    }
}

Etkinlikleri koordine etme

Bir etkinlik başka bir etkinliği başlattığında her ikisi de yaşam döngüsü geçişleri yaşar. İlk etkinlik çalışmayı durdurur ve Duraklatıldı veya Durduruldu durumuna girerken diğer etkinlik oluşturulur. Bu etkinlikler diske veya başka bir yere kaydedilen verileri paylaşıyorsa ikinci etkinlik oluşturulmadan önce ilk etkinliğin tamamen durdurulmadığını anlamak önemlidir. Bunun yerine, ikinci görevi başlatma süreci, ilk görevi durdurma süreciyle çakışır.

Yaşam döngüsü geri çağırmalarının sırası, özellikle iki etkinlik aynı süreçte (yani aynı uygulamada) olduğunda ve biri diğerini başlattığında iyi tanımlanır. A etkinliği B etkinliğini başlattığında gerçekleşen işlemlerin sırası şöyledir:

  1. A etkinliğinin onPause yöntemi yürütülür.
  2. B etkinliğinin onCreate, onStart ve onResume yöntemleri sırayla yürütülür. B etkinliği artık kullanıcı odağına sahip.
  3. A etkinliği artık ekranda görünmüyorsa onStop yöntemi yürütülür.

Bu yaşam döngüsü geri çağırma dizisi, bilgilerin bir etkinlikten diğerine geçişini yönetmenize olanak tanır.