ProfilingManager, sistem tetikleyicilerine dayalı profillerin yakalanmasını destekler. Sistem, kayıt sürecini yönetir ve sonuçta elde edilen profili uygulamanıza sağlar.
Tetikleyiciler, performans açısından kritik etkinliklerle ilişkilendirilir. Sistem tarafından kaydedilen profiller, bu tetikleyicilerle ilişkili kritik kullanıcı yolculukları (CUJ'ler) için ayrıntılı hata ayıklama bilgileri sağlar.
Geçmiş verileri yakalama
Birçok tetikleyici, etkinliğe kadar olan geçmiş verilerin analiz edilmesini gerektirir. Tetikleyici, genellikle temel neden yerine sorunun bir sonucudur. Bir profili yalnızca tetikleyici gerçekleştiğinde başlatırsanız asıl neden zaten kaybolmuş olabilir.
Örneğin, kullanıcı arayüzü iş parçacığında uzun süren bir işlem Uygulama Yanıt Vermiyor (ANR) hatasına neden olur. Sistem ANR'yi algılayıp uygulamaya sinyal gönderdiğinde işlem tamamlanmış olabilir. Bu noktada profil oluşturmak, gerçek engelleme çalışmasını kaçırır.
Bazı tetikleyicilerin tam olarak ne zaman gerçekleşeceğini tahmin etmek mümkün olmadığından profili önceden manuel olarak başlatmak mümkün değildir.
Neden tetikleyici tabanlı yakalama kullanmalısınız?
Profillendirme tetikleyicilerini kullanmanın temel nedeni, bir uygulamanın bu etkinlikler gerçekleşmeden önce manuel olarak kayda başlamasının mümkün olmadığı, öngörülemeyen etkinliklerle ilgili verileri yakalamaktır. Profillendirme tetikleyicileri şu amaçlarla kullanılabilir:
- Performans sorunlarında hata ayıklama: ANR'leri, bellek sızıntılarını ve diğer kararlılık sorunlarını teşhis edin.
- Kritik kullanıcı yolculuklarını optimize edin: Uygulama başlatma gibi akışları analiz edin ve iyileştirin.
- Kullanıcı davranışını anlama: Örneğin, kullanıcı tarafından başlatılan uygulama çıkışları gibi etkinlikler hakkında bilgi edinin.
Tetikleyici ayarlama
Aşağıdaki kodda, TRIGGER_TYPE_APP_FULLY_DRAWN tetikleyicisine nasıl kaydolunacağı ve bu tetikleyiciye nasıl sıklık sınırlaması uygulanacağı gösterilmektedir.
Kotlin
fun recordWithTrigger() { val profilingManager = applicationContext.getSystemService(ProfilingManager::class.java) val triggers = ArrayList<ProfilingTrigger>() val triggerBuilder = ProfilingTrigger.Builder(ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN) .setRateLimitingPeriodHours(1) triggers.add(triggerBuilder.build()) val mainExecutor: Executor = Executors.newSingleThreadExecutor() val resultCallback = Consumer<ProfilingResult> { profilingResult -> if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) { Log.d( "ProfileTest", "Received profiling result file=" + profilingResult.resultFilePath ) setupProfileUploadWorker(profilingResult.resultFilePath) } else { Log.e( "ProfileTest", "Profiling failed errorcode=" + profilingResult.errorCode + " errormsg=" + profilingResult.errorMessage ) } } profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback) profilingManager.addProfilingTriggers(triggers)
Java
public void recordWithTrigger() { ProfilingManager profilingManager = getApplicationContext().getSystemService( ProfilingManager.class); List<ProfilingTrigger> triggers = new ArrayList<>(); ProfilingTrigger.Builder triggerBuilder = new ProfilingTrigger.Builder( ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN); triggerBuilder.setRateLimitingPeriodHours(1); triggers.add(triggerBuilder.build()); Executor mainExecutor = Executors.newSingleThreadExecutor(); Consumer<ProfilingResult> resultCallback = new Consumer<ProfilingResult>() { @Override public void accept(ProfilingResult profilingResult) { if (profilingResult.getErrorCode() == ProfilingResult.ERROR_NONE) { Log.d( "ProfileTest", "Received profiling result file=" + profilingResult.getResultFilePath()); setupProfileUploadWorker(profilingResult.getResultFilePath()); } else { Log.e( "ProfileTest", "Profiling failed errorcode=" + profilingResult.getErrorCode() + " errormsg=" + profilingResult.getErrorMessage()); } } }; profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback); profilingManager.addProfilingTriggers(triggers);
Kod şu adımları gerçekleştirir:
- Get the manager:
ProfilingManagerhizmetini alır. - Tetikleyici tanımlama:
ProfilingTriggeriçinTRIGGER_TYPE_APP_FULLY_DRAWNoluşturur. Bu etkinlik, uygulama başlatma işlemini tamamladığını ve etkileşimli olduğunu bildirdiğinde gerçekleşir. - Sıklık sınırları ayarlama: Bu tetikleyiciye 1 saatlik sıklık sınırı uygular
(
setRateLimitingPeriodHours(1)). Bu, uygulamanın saatte birden fazla başlangıç profili kaydetmesini engeller. - Register listener: Sonucu işleyen geri çağırmayı tanımlamak için
registerForAllProfilingResultsişlevini çağırır. Bu geri çağırma,getResultFilePath()aracılığıyla kaydedilen profilin yolunu alır. - Tetikleyici ekleme:
ProfilingManagerile tetikleyici listesiniaddProfilingTriggerskullanarak kaydeder. - Etkinliği tetikleme:
reportFullyDrawn()işlevini çağırır. Bu işlev, sistem arka plan izlemesinin çalıştığı ve hız sınırlayıcı kotasının mevcut olduğu varsayılarak bir profil toplama işlemini tetikleyen sistemeTRIGGER_TYPE_APP_FULLY_DRAWNetkinliğini gönderir. Bu isteğe bağlı adım, uçtan uca akışı gösterir. Çünkü uygulamanızın bu tetikleyici içinreportFullyDrawn()işlevini çağırması gerekir.
İzi alma
Sistem, tetikleyici tabanlı profilleri diğer profillerle aynı dizine kaydeder. Tetiklenen izlemelerin dosya adı şu biçimdedir:
profile_trigger_<profile_type_code>_<datetime>.<profile-type-name>
ADB'yi kullanarak dosyayı çekebilirsiniz. Örneğin, ADB kullanarak örnek kodla yakalanan sistem izini çekmek için aşağıdaki gibi bir komut kullanabilirsiniz:
adb pull /data/user/0/com.example.sampleapp/files/profiling/profile_trigger_1_2025-05-06-14-12-40.perfetto-trace
Bu izleri görselleştirme hakkında ayrıntılı bilgi için Profil oluşturma verilerini alma ve analiz etme başlıklı makaleyi inceleyin.
Arka planda izleme özelliğinin işleyiş şekli
İşletim sistemi, tetikleyiciden önceki verileri yakalamak için düzenli olarak arka planda izleme başlatır. Bu arka plan izleme işlemi etkin durumdayken bir tetikleyici gerçekleşirse ve uygulamanız bu tetikleyici için kayıtlıysa sistem, izleme profilini uygulamanızın dizinine kaydeder. Daha sonra, profilde tetikleyiciye yol açan bilgiler yer alır.
Profil kaydedildikten sonra sistem, registerForAllProfilingResults öğesine sağlanan geri çağırma işlevini kullanarak uygulamanıza bildirim gönderir. Bu geri çağırma, ProfilingResult#getResultFilePath() çağrılarak erişilebilen, yakalanan profilin yolunu sağlar.
Sistem, cihaz performansı ve pil ömrü üzerindeki etkiyi azaltmak için arka plan izlemelerini sürekli olarak çalıştırmaz. Bunun yerine örnekleme yöntemi kullanılır. Sistem, belirli bir zaman aralığında (minimum ve maksimum süreyle) rastgele bir arka plan izleme başlatır. Bu izlerin rastgele aralıklarla yerleştirilmesi tetikleyici kapsamını iyileştirir.
Sistem tarafından tetiklenen profillerin sistem tarafından tanımlanan maksimum boyutu vardır. Bu nedenle, halka arabellek kullanırlar. Arabellek dolduğunda yeni izleme verileri en eski verilerin üzerine yazılır. Şekil 1'de gösterildiği gibi, arabellek dolarsa yakalanan izleme, arka plan kaydının tamamını kapsamayabilir. Bunun yerine, tetikleyiciye kadar olan en son etkinliği gösterir.
Tetikleyiciye özel sıklık sınırlaması uygulama
Yüksek sıklıkta tetikleme, uygulamanızın sıklık sınırlayıcı kotasını hızla tüketebilir. Hız sınırlayıcıyı daha iyi anlamak için Hız sınırlayıcı nasıl çalışır? başlıklı makaleyi incelemenizi öneririz. Tek bir tetikleyici türünün kotanızı tüketmesini önlemek için tetikleyiciye özel sıklık sınırlaması uygulayabilirsiniz.
ProfilingManager, uygulama tarafından tanımlanan tetikleyiciye özel sıklık sınırlamayı destekler. Bu sayede, mevcut hız sınırlayıcıya ek olarak zamana dayalı başka bir sınırlama katmanı ekleyebilirsiniz. Bir tetikleyici için belirli bir bekleme süresi ayarlamak üzere setRateLimitingPeriodHours API'sini kullanın. Bekleme süresi sona erdikten sonra özelliği tekrar tetikleyebilirsiniz.
Tetikleyicilerde yerel olarak hata ayıklama
Arka plan izlemeleri rastgele zamanlarda çalıştığından hata ayıklama tetikleyicilerini yerel olarak tetiklemek zordur. Test için arka planda izlemeyi zorlamak üzere aşağıdaki ADB komutunu kullanın:
adb shell device_config put profiling_testing system_triggered_profiling.testing_package_name <com.example.myapp>
Bu komut, sistemin belirtilen paket için sürekli bir arka plan izlemesi başlatmasını zorlar. Böylece, hız sınırlayıcı izin verirse her tetikleyici bir profil toplayabilir.
Yerel olarak hata ayıklarken hız sınırlayıcıyı devre dışı bırakma gibi diğer hata ayıklama seçeneklerini de etkinleştirebilirsiniz. Daha fazla bilgi için Yerel profilleme için hata ayıklama komutları başlıklı makaleyi inceleyin.