Uygulama başlatma süresi

Kullanıcılar, uygulamaların hızlı yüklenmesini ve yanıt vermesini bekler. Başlangıç süresi yavaş olan bir uygulama bu beklentiyi karşılamaz ve kullanıcıları hayal kırıklığına uğratabilir. Bu tür kötü deneyimler, kullanıcının uygulamanızı Play Store'da kötü puanlamasına veya uygulamanızı tamamen bırakmasına neden olabilir.

Bu sayfada, uygulamanızın başlatma süresini optimize etmenize yardımcı olacak bilgiler verilmektedir. Bu bilgiler arasında başlatma sürecinin iç işleyişine dair genel bakış, başlatma performansının nasıl profillendirileceği ve başlatma süresiyle ilgili bazı yaygın sorunların nasıl ele alınacağına dair ipuçları yer alır.

Farklı uygulama başlatma durumlarını anlama

Uygulama başlatma işlemi üç durumdan birinde gerçekleşebilir: baştan başlatma, hazır durumda başlatma veya çalışır durumda başlatma. Her durum, uygulamanızın kullanıcıya görünür hale gelmesinin ne kadar süreceğini etkiler. Sıfırdan başlatmada uygulamanız sıfırdan başlar. Diğer durumlarda ise sistemin, çalışan uygulamayı arka plandan ön plana getirmesi gerekir.

Her zaman baştan başlatma varsayımına göre optimizasyon yapmanızı öneririz. Bu işlem, sıcak ve hızlı başlatma performansını da artırabilir.

Uygulamanızı hızlı başlatma için optimize etmek istiyorsanız sistem ve uygulama düzeyinde neler olduğunu ve bu durumların her birinde nasıl etkileşimde bulunduklarını anlamanız faydalı olur.

Uygulama başlatma süresini belirlemek için kullanılan iki önemli metrik ilk görüntüleme süresi (TTID) ve tamamen çizilme süresidir (TTFD). TTID, ilk karenin gösterilmesi için gereken süreyi, TTFD ise uygulamanın tamamen etkileşimli hale gelmesi için gereken süreyi ifade eder. TTID, kullanıcılara uygulamanın yüklendiğini bildirdiği için, TTFD ise uygulamanın gerçekten kullanılabilir olduğu zamanı gösterdiği için her ikisi de eşit derecede önemlidir. Bu sürelerden biri çok uzunsa kullanıcı, uygulamanız tamamen yüklenmeden çıkabilir.

Baştan başlatma

Sıfırdan başlatma, uygulamanın sıfırdan başlamasını ifade eder. Bu, sistemin işlemi, bu başlangıca kadar uygulamanın işlemini oluşturduğu anlamına gelir. Sıfırdan başlatmalar, cihaz başlatıldığından veya sistem uygulamayı sonlandırdığından beri uygulamanızın ilk kez başlatılması gibi durumlarda gerçekleşir.

Bu durumda sistemin ve uygulamanın iş yükü diğer başlatma durumlarına göre daha fazla olduğundan, başlatma süresini en aza indirmenin en zor olduğu başlangıç türü sıfırdan başlatmadır.

Baştan başlatmanın başında sistemin üç görevi vardır:

  1. Uygulamayı yükleyip başlatın.
  2. Uygulama başlatıldıktan hemen sonra boş bir başlangıç penceresi gösterilir.
  3. Uygulama sürecini oluşturun.

Sistem uygulama sürecini oluşturur oluşturmaz, uygulama süreci sonraki aşamalardan sorumludur:

  1. Uygulama nesnesini oluşturun.
  2. Ana iş parçacığını başlatın.
  3. Ana etkinliği oluşturun.
  4. Görüntüleme sayısını artırmak
  5. Ekranı düzenleyin.
  6. İlk çekilişi yapın.

Uygulama işlemi ilk çizimi tamamladığında sistem işlemi, görüntülenen arka plan penceresini ana etkinlikle değiştirir. Bu noktada kullanıcı uygulamayı kullanmaya başlayabilir.

Şekil 1'de sistem ve uygulama işlemlerinin birbirleri arasında işleri nasıl devrettiği gösterilmektedir.

Şekil 1. Soğuk uygulama başlatmanın önemli kısımlarının görsel temsili.

Performans sorunları, uygulama ve etkinlik oluşturma sırasında ortaya çıkabilir.

Uygulama oluşturma

Uygulamanız başlatıldığında, sistem uygulamayı ilk kez çizme işlemini tamamlayana kadar boş başlangıç penceresi ekranda kalır. Bu noktada, sistem süreci uygulamanızın başlangıç penceresini değiştirerek kullanıcının uygulamayla etkileşimde bulunmasına olanak tanır.

Kendi uygulamanızda Application.onCreate() işlevini geçersiz kılarsanız sistem, uygulama nesnenizde onCreate() yöntemini çağırır. Ardından uygulama, kullanıcı arayüzü iş parçacığı olarak da bilinen ana iş parçacığını oluşturur ve ana etkinliğinizi oluşturma görevini bu iş parçacığına verir.

Bu noktadan itibaren sistem ve uygulama düzeyindeki işlemler, uygulama yaşam döngüsü aşamalarına göre ilerler.

Etkinlik oluşturma

Uygulama işlemi etkinliğinizi oluşturduktan sonra etkinlik aşağıdaki işlemleri gerçekleştirir:

  1. Değerleri başlatır.
  2. Yapıcıları çağırır.
  3. Etkinliğin mevcut yaşam döngüsü durumuna uygun olarak Activity.onCreate() gibi geri çağırma yöntemini çağırır.

Genellikle, onCreate() yöntemi, yükleme süresi üzerinde en büyük etkiye sahiptir. Bunun nedeni, en yüksek ek yükü olan işi yapmasıdır: görünümleri yükleme ve genişletme, etkinliğin çalışması için gereken nesneleri başlatma.

Hazır durumda başlatma

Hazır durumda başlatma, baştan başlatma sırasında gerçekleşen işlemlerin bir alt kümesini kapsar. Aynı zamanda, çalışır durumda başlatmaya kıyasla daha fazla ek yükü temsil eder. Aşağıdakiler gibi birçok olası durum, sıcak başlangıç olarak değerlendirilebilir:

  • Kullanıcı uygulamanızdan çıkar ancak uygulamayı yeniden başlatır. İşlem çalışmaya devam edebilir ancak uygulamanın onCreate() çağrısı kullanarak etkinliği sıfırdan oluşturması gerekir.

  • Sistem, uygulamanızı bellekten çıkarır ve kullanıcı uygulamayı yeniden başlatır. İşlemin ve etkinliğin yeniden başlatılması gerekir ancak görev, onCreate() içine iletilen kaydedilmiş örnek durumu paketinden bir miktar yararlanabilir.

Çalışır durumda başlatma

Uygulamanızın çalışır durumda başlatılması, baştan başlatılmasına kıyasla daha az ek yük oluşturur. Çalışır durumda başlatmada sistem, etkinliğinizi ön plana getirir. Uygulamanızın tüm etkinlikleri bellekte kalmaya devam ediyorsa uygulama, nesne başlatma, düzen ayrıştırma ve oluşturma işlemlerini tekrarlamaktan kaçınabilir.

Ancak onTrimMemory() gibi bellek kırpma etkinliklerine yanıt olarak bazı bellek temizlenirse bu nesnelerin çalışır durumda başlatma etkinliğine yanıt olarak yeniden oluşturulması gerekir.

Çalışır durumda başlatma, baştan başlatma senaryosunda olduğu gibi ekranda aynı davranışı gösterir. Sistem işlemi, uygulama etkinliği oluşturmayı tamamlayana kadar boş bir ekran gösterir.

Şekil 2. Çeşitli başlatma durumlarını ve ilgili süreçlerini gösteren bir diyagram. Her durum, çizilen ilk kareyle başlar.

Perfetto'da uygulama başlatmayı belirleme

Uygulama başlatma sorunlarını ayıklamak için uygulama başlatma aşamasında tam olarak nelerin yer aldığını belirlemek faydalıdır. Perfetto'da uygulamanın başlatılmasının tamamını belirlemek için şu adımları uygulayın:

  1. Perfetto'da, Android Uygulama Başlatmaları türetilmiş metriğinin bulunduğu satırı bulun. Bu seçeneği görmüyorsanız Cihaz üzerinde sistem izleme uygulamasını kullanarak izleme yakalamayı deneyin.

    Şekil 3. Perfetto'daki Android Uygulaması Başlatma türetilmiş metrik dilimi.
  2. İlişkili dilimi tıklayın ve dilimi seçmek için m tuşuna basın. Dilimin etrafında köşeli parantezler görünür ve bu parantezler, dilimin ne kadar sürdüğünü gösterir. Süre, Geçerli seçim sekmesinde de gösterilir.

  3. İşaretçiyi satırın üzerinde tuttuğunuzda görünen sabitleme simgesini tıklayarak Android Uygulama Başlangıçları satırını sabitleyin.

  4. Söz konusu uygulamanın bulunduğu satıra gidin ve satırı genişletmek için ilk hücreyi tıklayın.

  5. w tuşuna basarak ana ileti dizisini (genellikle en üstte) yakınlaştırın. Uzaklaştırmak, sola ve sağa gitmek için sırasıyla s, a, d tuşlarına basın.

    Şekil 4. Uygulamanın ana iş parçacığının yanındaki Android Uygulama Başlangıçları türetilmiş metrik dilimi.
  6. Türetilmiş metrikler dilimi, uygulama başlatma işlemine tam olarak nelerin dahil edildiğini görmeyi kolaylaştırır. Böylece hata ayıklama işlemine daha ayrıntılı bir şekilde devam edebilirsiniz.

Başlangıçları incelemek ve iyileştirmek için metrikleri kullanma

Başlatma süresi performansını doğru şekilde teşhis etmek için uygulamanızın başlatılmasının ne kadar sürdüğünü gösteren metrikleri izleyebilirsiniz. Android, uygulamanızda sorun olduğunu göstermek ve sorunu teşhis etmenize yardımcı olmak için çeşitli yöntemler sunar. Android vitals, bir sorun oluştuğunda sizi uyarabilir. Teşhis araçları ise sorunu teşhis etmenize yardımcı olabilir.

Başlangıç metriklerini kullanmanın avantajları

Android, soğuk ve sıcak uygulama başlatmalarını optimize etmek için ilk ekrana görüntülenene kadar geçen süre (TTID) ve tam ekrana görüntülenene kadar geçen süre (TTFD) metriklerini kullanır. Android Çalışma Zamanı (ART), gelecekteki başlatma işlemlerinin optimizasyonu için kodu verimli bir şekilde önceden derlemek üzere bu metriklerdeki verileri kullanır.

Daha hızlı başlatma işlemleri, uygulamanızla daha uzun süreli kullanıcı etkileşimine yol açar. Bu da erken çıkma, örneği yeniden başlatma veya farklı bir uygulamaya gitme durumlarını azaltır.

Android vitals

Android vitals, uygulamanızın başlatma süreleri çok uzun olduğunda Play Console'da sizi uyararak uygulamanızın performansını artırmanıza yardımcı olabilir.

Android vitals, uygulamanızın aşağıdaki başlangıç sürelerini aşırı olarak değerlendirir:

  • Yeni başlatma 5 saniye veya daha uzun sürüyor.
  • Hazırda başlatma 2 saniye veya daha uzun sürüyor.
  • Hot startup 1,5 saniye veya daha uzun sürüyor.

Android vitals, ilk ekrana görüntülenene kadar geçen süre (TTID) metriğini kullanır. Google Play'in Android vitals verilerini nasıl topladığı hakkında bilgi edinmek için Play Console belgelerine bakın.

İlk gösterime kalan süre

İlk gösterime kalan süre (TTID), uygulamanın kullanıcı arayüzünün ilk karesini göstermek için gereken süredir. Bu metrik, uygulamanın ilk kareyi oluşturması için gereken süreyi ölçer. Bu süreye, baştan başlatma : sıfırdan başlatma sırasında sürecin ilk kullanıma hazırlanması, baştan başlatma : sıfırdan başlatma veya hazır durumda başlatma sırasında etkinliğin oluşturulması ve ilk karenin görüntülenmesi dahildir. Uygulamanızın TTID'sini düşük tutmak, kullanıcıların uygulamanızın hızlı bir şekilde başlatıldığını görmelerini sağlayarak kullanıcı deneyimini iyileştirir. TTID, Android Framework tarafından her uygulama için otomatik olarak raporlanır. Uygulama başlatma için optimizasyon yaparken TTFD'ye kadar bilgi almak için reportFullyDrawn'yi uygulamanızı öneririz.

TTID, aşağıdaki etkinlik dizisini içeren toplam geçen süreyi temsil eden bir zaman değeri olarak ölçülür:

  • İşlemi başlatma
  • Nesneler başlatılıyor.
  • Etkinliği oluşturma ve başlatma
  • Düzen şişiriliyor.
  • Uygulamanın ilk kez çizilmesi.

TTID'yi alma

TTID'yi bulmak için Logcat komut satırı aracında Displayed adlı bir değer içeren çıkış satırını arayın. Bu değer, TTID'dir ve aşağıdaki örneğe benzer. Bu örnekte TTID, 3s534ms'dir:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

Android Studio'da TTID'yi bulmak için filtre açılır listesinden Logcat görünümünüzdeki filtreleri devre dışı bırakın ve ardından Şekil 5'te gösterildiği gibi Displayed zamanını bulun. Bu günlük, uygulamanın kendisi tarafından değil sistem sunucusu tarafından sunulduğu için filtrelerin devre dışı bırakılması gerekir.

Şekil 5. Devre dışı bırakılan filtreler ve logcat'teki Displayed değeri.

Logcat çıkışındaki Displayed metriği, tüm kaynaklar yüklenip görüntülenene kadar geçen süreyi mutlaka yakalamaz. Düzen dosyasında referans verilmeyen veya uygulamanın nesne başlatma işleminin bir parçası olarak oluşturduğu kaynakları hariç tutar. Bu kaynaklar, yüklenmeleri satır içi bir işlem olduğu ve uygulamanın ilk gösterimini engellemediği için hariç tutulur.

Bazen Logcat çıkışındaki Displayed satırında toplam süre için ek bir alan bulunur. Örneğin:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)

Bu durumda, ilk ölçüm yalnızca ilk çizilen etkinlik için yapılır. total süre ölçümü, uygulama işlemi başladığında başlar ve önce başlatılan ancak ekranda hiçbir şey göstermeyen başka bir etkinliği içerebilir. total zaman ölçümü yalnızca tek etkinlik ile toplam başlatma süreleri arasında fark olduğunda gösterilir.

Android Studio'da Logcat'i kullanmanızı öneririz. Ancak Android Studio kullanmıyorsanız uygulamanızı adb shell activity manager komutu ile çalıştırarak da TTID'yi ölçebilirsiniz. Örneğin:

adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN

Displayed metriği, Logcat çıkışında eskisi gibi görünür. Terminal pencerenizde aşağıdakiler gösterilir:

Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete

-c ve -a bağımsız değişkenleri isteğe bağlıdır ve <category> ile <action> değerlerini belirtmenize olanak tanır.

Tam gösterime kalan süre

Tam görüntüleme süresi (TTFD), bir uygulamanın kullanıcı için etkileşimli hale gelmesi için gereken süredir. Uygulamanın kullanıcı arayüzünün ilk karesinin ve ilk kare görüntülendikten sonra eşzamansız olarak yüklenen içeriğin gösterilmesi için geçen süre olarak raporlanır. Genellikle bu, uygulamanın bildirdiği şekilde ağdan veya diskten yüklenen birincil içeriktir. Diğer bir deyişle, TTFD, TTID'nin yanı sıra uygulamanın kullanılabilir hale gelmesi için geçen süreyi de içerir. Uygulamanızın TTFD'sini düşük tutmak, kullanıcıların uygulamanızla hızlı bir şekilde etkileşim kurmasına olanak tanıyarak kullanıcı deneyimini iyileştirir.

Sistem, Choreographer, etkinliğin onDraw() yöntemini çağırdığında ve bunu ilk kez çağırdığını bildiğinde TTID'yi belirler. Ancak her uygulama farklı davrandığı için sistem, TTFD'nin ne zaman belirleneceğini bilemez. TTFD'yi belirlemek için uygulamanın, tamamen çizilmiş duruma ulaştığında sisteme sinyal vermesi gerekir.

TTFD'yi alma

TTFD'yi bulmak için ComponentActivity öğesinin reportFullyDrawn() yöntemini çağırarak tamamen çizilmiş durumu belirtin. reportFullyDrawn yöntemi, uygulamanın tamamen çizildiği ve kullanılabilir durumda olduğu zamanı bildirir. TTFD, sistemin uygulama başlatma amacını aldığı andan reportFullyDrawn() çağrılana kadar geçen süredir. reportFullyDrawn() işlevini çağırmazsanız TTFD değeri raporlanmaz.

TTFD'yi ölçmek için kullanıcı arayüzünü ve tüm verileri tamamen çizdikten sonra reportFullyDrawn() işlevini çağırın. Sistem tarafından ölçülen ilk etkinliğin penceresi ilk kez çizilip görüntülenmeden önce reportFullyDrawn() işlevini çağırmayın. Aksi takdirde sistem, sistem tarafından ölçülen süreyi bildirir. Diğer bir deyişle, sistem TTID'yi algılamadan önce reportFullyDrawn() çağrısı yaparsanız sistem hem TTID'yi hem de TTFD'yi aynı değer olarak bildirir ve bu değer TTID değeridir.

reportFullyDrawn() kullandığınızda Logcat, aşağıdaki örneğe benzer bir çıkış gösterir. Bu örnekte TTFD 1 sn 54 ms'dir:

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

Logcat çıktısı bazen İlk görüntüleme süresi bölümünde açıklandığı gibi total süresini içerir.

Görüntüleme süreleriniz istediğinizden daha yavaşsa başlatma sürecindeki darboğazları belirlemeye çalışabilirsiniz.

Tamamen çizilmiş durumun elde edildiğini bildiğiniz temel durumlarda, tamamen çizilmiş durumu belirtmek için reportFullyDrawn() kullanabilirsiniz. Ancak arka plan iş parçacıklarının, tamamen çizilmiş durum elde edilmeden önce arka plan çalışmasını tamamlaması gereken durumlarda daha doğru bir TTFD ölçümü için reportFullyDrawn() değerini geciktirmeniz gerekir. reportFullyDrawn() nasıl erteleneceğini öğrenmek için aşağıdaki bölüme bakın.

Başlatma zamanlaması doğruluğunu artırma

Uygulamanızda geç yükleme yapılıyorsa ve ilk gösterimde tüm kaynaklar yer almıyorsa (ör. uygulamanız ağdan resim getiriyorsa) reportFullyDrawn işlevini, uygulamanız kullanılabilir hale gelene kadar erteleyebilirsiniz. Böylece liste doldurma işlemini karşılaştırma zamanlamanıza dahil edebilirsiniz.

Örneğin, kullanıcı arayüzünde RecyclerView veya geç yüklenen liste gibi dinamik bir liste varsa bu liste, ilk kez çizildikten ve dolayısıyla kullanıcı arayüzü tamamen çizilmiş olarak işaretlendikten sonra tamamlanan bir arka plan göreviyle doldurulabilir. Bu gibi durumlarda liste doldurma, karşılaştırmaya dahil edilmez.

Liste doldurma işlemini karşılaştırma zamanlamanıza dahil etmek için getFullyDrawnReporter() kullanarak FullyDrawnReporter alın ve uygulama kodunuza bir muhabir ekleyin. Arka plan görevi listeyi doldurmayı bitirdikten sonra muhabiri serbest bırakın.

FullyDrawnReporter, eklenen tüm raporlar serbest bırakılana kadar reportFullyDrawn() yöntemini çağırmaz. Arka plan işlemi tamamlanana kadar bir muhabir eklediğinizde, zamanlamalar başlangıç zamanlaması verilerindeki listeyi doldurmak için gereken süreyi de içerir. Bu, uygulamanın kullanıcı açısından davranışını değiştirmez ancak başlatma zamanlaması verilerinin, listenin doldurulması için gereken süreyi içermesine olanak tanır. reportFullyDrawn(), sıradan bağımsız olarak tüm görevler tamamlanana kadar çağrılmaz.

Aşağıdaki örnekte, her biri kendi raporlayıcısını kaydederek birden fazla arka plan görevini eşzamanlı olarak nasıl çalıştırabileceğiniz gösterilmektedir:

Kotlin

class MainActivity : ComponentActivity() {

    sealed interface ActivityState {
        data object LOADING : ActivityState
        data object LOADED : ActivityState
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            var activityState by remember {
                mutableStateOf(ActivityState.LOADING as ActivityState)
            }
            fullyDrawnReporter.addOnReportDrawnListener {
                activityState = ActivityState.LOADED
            }
            ReportFullyDrawnTheme {
                when(activityState) {
                    is ActivityState.LOADING -> {
                        // Display the loading UI.
                    }
                    is ActivityState.LOADED -> {
                        // Display the full UI.
                    }
                }
            }
            SideEffect {
                fullyDrawnReporter.addReporter()
                lifecycleScope.launch(Dispatchers.IO) {
                    // Perform the background operation.
                    fullyDrawnReporter.removeReporter()
                }
                fullyDrawnReporter.addReporter()
                lifecycleScope.launch(Dispatchers.IO) {
                    // Perform the background operation.
                    fullyDrawnReporter.removeReporter()
                }
            }
        }
    }
}

Java

public class MainActivity extends ComponentActivity {
    private FullyDrawnReporter fullyDrawnReporter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        fullyDrawnReporter = getFullyDrawnReporter();
        fullyDrawnReporter.addOnReportDrawnListener(() -> {
            // Trigger the UI update.
            return Unit.INSTANCE;
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                fullyDrawnReporter.addReporter();
                // Do the background work.
                fullyDrawnReporter.removeReporter();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                fullyDrawnReporter.addReporter();
                // Do the background work.
                fullyDrawnReporter.removeReporter();
            }
        }).start();
    }
}

Uygulamanızda Jetpack Compose kullanılıyorsa tamamen çizilmiş durumu belirtmek için aşağıdaki API'leri kullanabilirsiniz:

  • ReportDrawn: Composable'ınızın hemen etkileşime hazır olduğunu gösterir.
  • ReportDrawnWhen: Bir koşul alır (ör. list.count > 0). Bu koşul, composable'ınızın etkileşime hazır olduğunu belirtir.
  • ReportDrawnAfter: Tamamlandığında composable'ınızın etkileşime hazır olduğunu belirten bir askıya alma yöntemi kullanır.
Darboğazları belirleme

Darboğazları aramak için Android Studio CPU Profiler'ı kullanabilirsiniz. Daha fazla bilgi için CPU profiler ile CPU etkinliğini inceleme başlıklı makaleyi inceleyin.

Ayrıca, uygulamalarınızın ve etkinliklerinizin onCreate() yöntemlerindeki satır içi izleme sayesinde olası darboğazlar hakkında bilgi edinebilirsiniz. Satır içi izleme hakkında bilgi edinmek için Trace işlevleriyle ilgili dokümanlara ve sistem izlemeye genel bakış başlıklı makaleye göz atın.

Sık karşılaşılan sorunları çözme

Bu bölümde, uygulama başlatma performansını sıklıkla etkileyen çeşitli sorunlar ele alınmaktadır. Bu sorunlar genellikle uygulama ve etkinlik nesnelerinin başlatılmasıyla ve ekranların yüklenmesiyle ilgilidir.

Yoğun uygulama başlatma

Kodunuz Application nesnesini geçersiz kıldığında ve bu nesneyi başlatırken ağır işlemler veya karmaşık mantık yürüttüğünde başlatma performansı düşebilir. Application alt sınıflarınız henüz yapılması gerekmeyen başlatma işlemleri gerçekleştiriyorsa uygulamanız başlatma sırasında zaman kaybedebilir.

Bazı başlatma işlemleri tamamen gereksiz olabilir. Örneğin, uygulama aslında bir amaç doğrultusunda başlatıldığında ana etkinliğin durum bilgilerinin başlatılması gibi. Uygulama, bir amaçla yalnızca daha önce başlatılmış durum verilerinin bir alt kümesini kullanır.

Uygulama başlatma sırasında karşılaşılan diğer zorluklar arasında, etkili veya çok sayıda olan çöp toplama etkinlikleri ya da başlatma işlemiyle eşzamanlı olarak gerçekleşen disk G/Ç'si yer alır. Bu durum, başlatma sürecini daha da engeller. Çöp toplama özellikle Dalvik çalışma zamanında dikkate alınır. Android çalışma zamanı (ART) çöp toplama işlemini eşzamanlı olarak gerçekleştirerek bu işlemin etkisini en aza indirir.

Sorunu teşhis etme

Sorunu teşhis etmek için yöntem izleme veya satır içi izleme özelliğini kullanabilirsiniz.

Yöntem izleme

CPU Profiler'ı çalıştırmak, callApplicationOnCreate() yönteminin sonunda com.example.customApplication.onCreate yönteminizi çağırdığını gösterir. Araç, bu yöntemlerin yürütülmesinin uzun sürdüğünü gösteriyorsa hangi işlemlerin gerçekleştiğini görmek için daha ayrıntılı bir inceleme yapın.

Satır içi izleme

Aşağıdakiler de dahil olmak üzere olası sorun kaynaklarını araştırmak için satır içi izlemeyi kullanın:

  • Uygulamanızın ilk onCreate() işlevi.
  • Uygulamanızın başlattığı tüm genel tekil nesneler.
  • Performans sorunu sırasında gerçekleşebilecek tüm disk G/Ç'leri, seri durumdan çıkarma veya sıkı döngüler.

Sorunun çözümleri

Sorun gereksiz başlatmalardan veya disk G/Ç'den kaynaklanıyor olsa da çözüm tembel başlatmadır. Başka bir deyişle, yalnızca hemen ihtiyaç duyulan nesneleri başlatın. Global statik nesneler oluşturmak yerine, uygulamanın nesneleri yalnızca ilk kez ihtiyaç duyduğunda başlatıldığı tekil örnek (singleton) kalıbına geçin.

Ayrıca, nesneleri ve bağımlılıkları ilk kez yerleştirildiklerinde oluşturan Hilt gibi bir bağımlılık yerleştirme çerçevesi kullanmayı da düşünebilirsiniz.

Uygulamanız, başlatma sırasında uygulama bileşenlerini başlatmak için içerik sağlayıcıları kullanıyorsa bunun yerine App Startup kitaplığını kullanmayı düşünebilirsiniz.

Yoğun aktivite başlatma

Etkinlik oluşturma genellikle çok fazla ek iş gerektirir. Genellikle, performans iyileştirmeleri elde etmek için bu çalışmayı optimize etme fırsatları vardır. Bu tür yaygın sorunlar şunlardır:

  • Büyük veya karmaşık düzenleri şişirme
  • Diske veya ağ G/Ç'ye ekran çizimini engelleme.
  • Bit eşlemleri yükleme ve kod çözme
  • VectorDrawable nesneleri rasterleştirme.
  • Etkinliğin diğer alt sistemlerinin başlatılması.

Sorunu teşhis etme

Bu durumda da hem yöntem izleme hem de satır içi izleme yararlı olabilir.

Yöntem izleme

CPU Profiler'ı kullanırken uygulamanızın Application alt sınıf oluşturucularına ve com.example.customApplication.onCreate() yöntemlerine dikkat edin.

Araç, bu yöntemlerin yürütülmesinin uzun sürdüğünü gösteriyorsa hangi işlemlerin yapıldığını görmek için daha ayrıntılı bir inceleme yapın.

Satır içi izleme

Aşağıdakiler de dahil olmak üzere olası sorun kaynaklarını araştırmak için satır içi izlemeyi kullanın:

  • Uygulamanızın ilk onCreate() işlevi.
  • Başlattığı tüm genel tekil nesneler.
  • Performans sorunu sırasında gerçekleşebilecek tüm disk G/Ç'leri, seri durumdan çıkarma veya sıkı döngüler.

Sorunun çözümleri

Birçok olası darboğaz vardır ancak sık karşılaşılan iki sorun ve çözümleri aşağıda verilmiştir:

  • Görünüm hiyerarşiniz ne kadar büyükse uygulamanın bunu genişletmesi o kadar uzun sürer. Bu sorunu gidermek için aşağıdaki iki adımı uygulayabilirsiniz:
    • Gereksiz veya iç içe yerleştirilmiş düzenleri azaltarak görünüm hiyerarşinizi düzleştirin.
    • Kullanıcı arayüzünün, başlatma sırasında görünmesi gerekmeyen kısımlarını şişirmeyin. Bunun yerine, uygulamanın daha uygun bir zamanda genişletebileceği alt hiyerarşiler için yer tutucu olarak ViewStub nesnesi kullanın.
  • Tüm kaynak başlatma işlemlerinin ana iş parçacığında yapılması da başlatma işlemini yavaşlatabilir. Bu sorunu aşağıdaki şekilde giderebilirsiniz:
    • Tüm kaynak başlatma işlemlerini, uygulamanın farklı bir iş parçacığında geç gerçekleştirebileceği şekilde taşıyın.
    • Uygulamanın görünümlerinizi yükleyip göstermesine izin verin, ardından bit eşlemlere ve diğer kaynaklara bağlı görsel özellikleri güncelleyin.

Özel başlangıç ekranları

Android 11'de (API düzeyi 30) veya önceki sürümlerde özel bir başlangıç ekranı uygulamak için daha önce aşağıdaki yöntemlerden birini kullandıysanız başlatma sırasında ek süre eklendiğini görebilirsiniz:

  • Başlatma sırasında sistem tarafından çizilen ilk boş ekranı kapatmak için windowDisablePreview tema özelliğini kullanın.
  • Özel bir Activity kullanma

Android 12'den itibaren SplashScreen API'ye geçiş yapılması zorunludur. Bu API, başlatma süresini kısaltır ve başlangıç ekranınızı aşağıdaki şekillerde ayarlamanıza olanak tanır:

Ayrıca, uyumluluk kitaplığı, geriye dönük uyumluluğu etkinleştirmek ve tüm Android sürümlerinde başlangıç ekranı gösterimi için tutarlı bir görünüm ve tarz oluşturmak üzere SplashScreen API'yi geriye dönük olarak taşır.

Ayrıntılar için Splash screen migration guide (Açılış ekranı taşıma rehberi) başlıklı makaleyi inceleyin.