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. O anda profil oluşturmaya başlamak, gerçek engelleme çalışmasını kaçırmanıza neden olur.
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 kullanılmalıdır?
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 şunlar için 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: Örneğin, 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. - Hız sınırları belirleme: Bu tetikleyiciye 1 saatlik hız 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: Tetikleyici listesini
ProfilingManagerileaddProfilingTriggerskullanarak kaydeder. - Etkinliği tetikleme: Bir sistem arka plan izinin çalıştığı ve hız sınırlayıcı kotanın mevcut olduğu varsayılarak profil toplama işlemini tetikleyen sisteme
TRIGGER_TYPE_APP_FULLY_DRAWNetkinliğini yayanreportFullyDrawn()işlevini çağırır. 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'yi kullanarak örnek kod ile 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
İşlemden önceki verileri yakalamak için işletim sistemi, 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 kaydedilmişse sistem, izleme profilini uygulamanızın dizinine kaydeder. Ardından, profilde tetikleyiciye yol açan bilgiler yer alır.
Profil kaydedildikten sonra sistem, registerForAllProfilingResults için sağlanan geri çağırma işlevini kullanarak uygulamanızı bilgilendirir. 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 tetiklenen işlemler, 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, uygulamayla 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.
Ayrıca, yerel olarak hata ayıklarken hız sınırlayıcıyı devre dışı bırakmak gibi diğer hata ayıklama seçeneklerini de etkinleştirebilirsiniz. Daha fazla bilgi için Yerel profil oluşturma için hata ayıklama komutları başlıklı makaleyi inceleyin.