JankStats kitaplığı hesabınızdaki performans sorunlarını izleyip analiz etmenize izin verir. Jank, oluşturulması çok uzun süren uygulama çerçeveleri ve JankStats kitaplığı da uygulamanızın olumsuzluk istatistikleriyle ilgili raporlar sunar.
İşlemler
JankStats, aşağıdakiler de dahil olmak üzere mevcut Android platformu özelliklerini temel alarak geliştirildi FrameMetrics API Android 7 (API düzeyi 24) ve sonraki sürümlerde veya önceki sürümlerde OnPreDrawListener'da sürümleri vardır. Bu mekanizmalar, uygulamaların, karelerin ne kadar sürdüğünü belirir. JanksStats kitaplığını oluşturan iki ek özellik vardır: daha dinamik ve kullanımı daha kolay: jank bulguları ve kullanıcı arayüzü durumu.
Jank buluşsal yöntemler
Kare sürelerini izlemek için FrameMetrics'i kullanabilirsiniz, ancak FrameMetrics oluşabilecek olumsuzluğun belirlenmesine yardımcı olmayı teklif eder. Ancak JankStats'ın aksatmanın ne zaman gerçekleştiğini belirlemek için yapılandırılabilir, dahili mekanizmalar yararlı hale getirir.
Kullanıcı arayüzü durumu
Genellikle uygulamanızdaki performans sorunlarının bağlamını bilmeniz gerekir. Örneğin, FrameMetrics kullanan karmaşık, birden çok ekranlı bir uygulama geliştirirseniz ve uygulamanızda genelde son derece hantal çerçeveler olduğunu fark ederseniz sorunun nerede, ne olduğunu ve sorunun ne olduğunu öğrenerek ve bunu tekrarlamanın yolları arasındadır.
JankStats, aşağıdakileri yapmanıza olanak tanıyan bir state
API'si sunarak bu sorunu çözer:
kitaplıkla iletişim kurarak uygulama Etkinliği hakkında bilgi sağlar. Zaman
JankStats, düzgün çalışmayan bir çerçeveyle ilgili bilgileri günlüğe kaydeder.
neden olabilir.
Kullanım
JankStats'ı kullanmaya başlamak için her örnek için kitaplığı örneklendirin ve etkinleştirin
Window
. Her JankStats nesnesi verileri izler
yalnızca Window
içinde olması gerekir. Kitaplığı örneklendirmek için Window
örneği gerekir
bir OnFrameListener
ile birlikte
işleyiciyi ifade eder. Her ikisi de metrikleri müşteriye göndermek için kullanılır. Dinleyiciye çağrıda bulunan:
Her karede FrameData
ve şu konular hakkında ayrıntılı bilgi verir:
- Kare başlangıç zamanı
- Süre değerleri
- Çerçevenin olumsuzluk olarak kabul edilip edilmeyeceği
- Uygulama durumu hakkında bilgiler içeren bir dizi Dize çifti kare sırasında
JankStats'ı daha faydalı hale getirmek için uygulamaların kitaplığı
FrameData'daki raporlama için alakalı kullanıcı arayüzü durum bilgilerini içerir. Şunları yapabilirsiniz:
aracılığıyla
PerformanceMetricsState
Tüm durum yönetimi mantığının ve API'lerin sunulduğu API (doğrudan JankStats değil)
canlı yayınlar.
Başlatma
JankStats kitaplığını kullanmaya başlamak için önce Gradle dosyası:
implementation "androidx.metrics:metrics-performance:1.0.0-beta01"
Daha sonra, her bir Window
için JankStats'ı başlatın ve etkinleştirin. Şunu da duraklatmalısınız:
JankStats, bir Etkinlik arka planda olduğunda izleme yapıyor. Oluştur ve etkinleştir
Etkinlik geçersiz kılma işlemlerinizdeki JankStats nesnesi:
class JankLoggingActivity : AppCompatActivity() {
private lateinit var jankStats: JankStats
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
// metrics state holder can be retrieved regardless of JankStats initialization
val metricsStateHolder = PerformanceMetricsState.getHolderForHierarchy(binding.root)
// initialize JankStats for current window
jankStats = JankStats.createAndTrack(window, jankFrameListener)
// add activity name as state
metricsStateHolder.state?.putState("Activity", javaClass.simpleName)
// ...
}
Yukarıdaki örnek, mevcut JankStats nesnesini oluşturduktan sonraki etkinlik. Gelecekteki tüm FrameData raporları bu JankStats nesnesi için oluşturulduğunda artık Etkinlik bilgileri de yer alıyor.
JankStats.createAndTrack
yöntemi, bir Window
referansı alır
nesnesidir. Bu, söz konusu Window
içindeki Görünüm hiyerarşisi için bir proxy'dir ve
Window
için. jankFrameListener
, kullanılan iş parçacığında çağrıldı
bu bilgileri platformdan JankStats'a dahili olarak iletmek için çalışıyor.
Herhangi bir JankStats nesnesinde izleme ve raporlamayı etkinleştirmek için
isTrackingEnabled = true
numaralı telefonu arayın. Varsayılan olarak etkin olsa da
Bir etkinliğin duraklatılması izlemeyi devre dışı bırakır. Bu durumda, yeniden etkinleştirme işlemini
izlemelisiniz. Takibi durdurmak için isTrackingEnabled = false
numaralı telefonu arayın.
override fun onResume() {
super.onResume()
jankStats.isTrackingEnabled = true
}
override fun onPause() {
super.onPause()
jankStats.isTrackingEnabled = false
}
Raporlama
JankStats kitaplığı her kare için tüm veri izlemenizi
OnFrameListener
tek bir fonksiyondur. Uygulamalar bu verileri depolayıp toplayabilir
daha sonra yüklemek üzere verileri içerebilir. Daha fazla bilgi için
Toplama bölümünde verilen örneklere göz atın.
Uygulamanızın alması için OnFrameListener
oluşturup sağlamanız gerekir
çerçeve oluşturmak. Bu dinleyici, her karede sürekli olarak
.
private val jankFrameListener = JankStats.OnFrameListener { frameData ->
// A real app could do something more interesting, like writing the info to local storage and later on report it.
Log.v("JankStatsSample", frameData.toString())
}
Dinleyici,
FrameData
nesnesini tanımlayın. Bu
istenen çerçeveyle ilgili şu bilgileri içerir:
isjank
: Çerçevede olumsuzluk yaşanıp yaşanmadığını gösteren bir boole işareti.frameDurationUiNanos
: Karenin süresi (nanosaniye cinsinden).frameStartNanos
: Çerçevenin başladığı zaman (nanosaniye cinsinden).states
: Kare sırasında uygulamanızın durumu.
Android 12 (API düzeyi 31) veya sonraki bir sürümü kullanıyorsanız şunları yapabilirsiniz: kare süreleriyle ilgili daha fazla veri açığa çıkarmak için aşağıdakileri kullanın:
FrameDataApi24
frameDurationCpuNanos
sağlar değerini değiştirin.FrameDataApi31
frameOverrunNanos
sağlar geçen süreyi gösterir. Bu süre, karenin tamamlanması için geçen süreyi belirir.
StateInfo
hizmetini kullan
dinlemesine olanak tanıması gerekir.
OnFrameListener
öğesinin, dahili olarak kullanılan ileti dizisinde çağrıldığını unutmayın.
çerçeve başına bilgileri JankStats'a iletmektir.
Android sürüm 6 (API düzeyi 23) ve önceki sürümlerde bu, Ana (UI) iş parçacığıdır.
Android sürüm 7 (API düzeyi 24) ve sonraki sürümlerde
iş parçacığı (FrameMetrics için oluşturuldu ve FrameMetrics tarafından kullanılıyor). Her iki durumda da,
hızlı bir şekilde geri arama yapabilir ve
görebilirsiniz.
Ayrıca, geri çağırmada gönderilen FrameData nesnesinin çerçevesini kullanarak veri raporlaması için yeni nesneler ayırma zorunu ortadan kaldırın. Bunun anlamı şudur: bu nesnenin ne olması gerektiği için bu verileri başka bir yere kopyalayıp geri çağırma işlevi döndürülür.
Toplanıyor
Uygulama kodunuzun kare başına verileri birleştirmesini istersiniz. Bu da
bilgileri kendiniz kaydedebilir ve yükleyebilirsiniz. Her ne kadar ayrıntılı
kaydetme ve yükleme ile ilgili konular alfa JankStats API'nin kapsamı dışındadır.
kare başına verilerin toplanmasıyla ilgili ön Etkinlik'i görüntüleyebilirsiniz.
JankAggregatorActivity
kullanarak daha geniş bir koleksiyona
GitHub deposu.
JankAggregatorActivity
kendi raporlamasını katmanlandırmak için JankStatsAggregator
sınıfını kullanır
sağlamak için JankStats OnFrameListener
mekanizmasının en üst kısmındaki
yalnızca anlamanızı sağlayacak olan bilgi koleksiyonunu
pek çok çerçeveyi
kapsıyor.
Doğrudan JankStats nesnesi oluşturmak yerine JankAggregatorActivity
bir JankStatsAggregator oluşturur
nesnesini ifade eder:
class JankAggregatorActivity : AppCompatActivity() {
private lateinit var jankStatsAggregator: JankStatsAggregator
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
// Metrics state holder can be retrieved regardless of JankStats initialization.
val metricsStateHolder = PerformanceMetricsState.getHolderForHierarchy(binding.root)
// Initialize JankStats with an aggregator for the current window.
jankStatsAggregator = JankStatsAggregator(window, jankReportListener)
// Add the Activity name as state.
metricsStateHolder.state?.putState("Activity", javaClass.simpleName)
}
JankAggregatorActivity
uygulamasında duraklatmak ve
takibi devam ettirmek için bir sinyal olarak pause()
etkinliğini ekleyerek
yaşam döngüsü değişiklikleri bir rapor gibi göründüğünden, issueJankReport()
çağrısı içeren bir rapor
uygulamadaki olumsuzluk durumunu yakalamak için uygun bir zaman belirleyin:
override fun onResume() {
super.onResume()
jankStatsAggregator.jankStats.isTrackingEnabled = true
}
override fun onPause() {
super.onPause()
// Before disabling tracking, issue the report with (optionally) specified reason.
jankStatsAggregator.issueJankReport("Activity paused")
jankStatsAggregator.jankStats.isTrackingEnabled = false
}
Yukarıdaki örnek kod, bir uygulamanın JankStats'ı etkinleştirmesi ve çerçeve verileri.
Eyaleti yönetme
JankStats'ı özelleştirmek için diğer API'leri çağırmak isteyebilirsiniz. Örneğin, uygulama durumu bilgilerinin eklenmesi, çerçeve verilerini şu şekilde daha yararlı hale getirir: aksamaya yol açan çerçeveler için bağlam sağlar.
Bu statik yöntem,
MetricsStateHolder
nesnesini ifade eder.
PerformanceMetricsState.getHolderForHierarchy(view: View): MetricsStateHolder
Etkin bir hiyerarşideki herhangi bir görünüm kullanılabilir. Dahili olarak bu,
onunla ilişkilendirilmiş mevcut bir Holder
nesnesi olup olmadığı
görebilirsiniz. Bu bilgiler, sayfanın en üstündeki görünümde önbelleğe alınır
hiyerarşik olarak düzenlenmiştir. Böyle bir nesne yoksa getHolderForHierarchy()
bir tane oluşturur.
Statik getHolderForHierarchy()
yöntemi, önbelleğe alma zorunluluğunu ortadan kaldırır.
sahip örneğini daha sonra almak üzere bir yere alır ve
kodda herhangi bir yerde bulunan mevcut bir durum nesnesini (hatta kitaplık kodunda
aksi takdirde orijinal örneğe erişemez).
Döndürülen değerin, durum nesnesinin kendisi değil, bir tutucu nesne olduğunu unutmayın. İlgili içeriği oluşturmak için kullanılan tutucunun içindeki durum nesnesinin değeri yalnızca JankStats tarafından ayarlanır. O Bir uygulama, bunu içeren pencere için JankStats nesnesi oluşturursa durum nesnesini görebilirsiniz. hazırlanır ve oluşturulur. Aksi takdirde, JankStats bilgileri izlemeden durum nesnesine gerek yoktur ve uygulama veya kitaplık için gerekli değildir kodu kullanma.
Bu yaklaşım sayesinde
JankStats'ın doldurabileceği bir tutucu alın. Harici kod
her an sahibini isteyebilir. Arayanlar hafif Holder
öğesini önbelleğe alabilir
nesneye belirleyebilir ve öğenin değerine bağlı olarak, durumu ayarlamak için istediğiniz zaman kullanabilirsiniz.
dahili state
mülkü olup, bu mülk aşağıdaki örnek kodda olduğu gibidır; durum yalnızca
sahibin dahili durum özelliği null olmadığında:
val metricsStateHolder = PerformanceMetricsState.getHolderForHierarchy(binding.root)
// ...
metricsStateHolder.state?.putState("Activity", javaClass.simpleName)
Kullanıcı arayüzü/uygulama durumunu kontrol etmek için bir uygulama, durum ekleyebilir (veya kaldırabilir)
putState
ve removeState
yöntemleriyle gerçekleştirebilirsiniz. JankStats
anlamına gelir. Bir kare durumun başlangıç ve bitiş zamanıyla çakışıyorsa
çerçeve.
Herhangi bir eyalet için iki bilgi ekleyin: key
("RecyclerView" gibi bir eyalet kategorisi) ve value
(
"kaydırma" gibi).
Hayır olduğunda, removeState()
yöntemini kullanarak durumları kaldırın
Böylece, yanlış veya yanıltıcı bilgilerin bildirilmemesi için daha uzun süre geçerli olurlar.
çerçeve verileriyle karşılaştırabilirsiniz.
Daha önce eklenmiş bir key
ile putState()
çağrısı yapmak, şu numaranın yerine geçer:
bu durumdaki mevcut value
taneyi yenisiyle değiştirin.
State API'nin putSingleFrameState()
sürümü,
yalnızca bir kez (raporlanan sonraki karede) günlüğe kaydedilir. Sistem, otomatik olarak
yanlışlıkla eski durumu devre dışı bırakmadığınızdan emin olmak için,
kodunuz. Tek kare eşdeğerinin olmadığını unutmayın
removeState()
, JankStats tek kare durumlarını otomatik olarak kaldırdığından emin olur.
private val scrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
// check if JankStats is initialized and skip adding state if not
val metricsState = metricsStateHolder?.state ?: return
when (newState) {
RecyclerView.SCROLL_STATE_DRAGGING -> {
metricsState.putState("RecyclerView", "Dragging")
}
RecyclerView.SCROLL_STATE_SETTLING -> {
metricsState.putState("RecyclerView", "Settling")
}
else -> {
metricsState.removeState("RecyclerView")
}
}
}
}
Eyaletler için kullanılan anahtarın, aynı zamanda
gözden geçireceğiz. Özellikle, aynı key
değerine sahip bir eyalet
eklendiğinde, bu önceki değerin yerini alırsa
düzeninizde farklı örnekleri olabilecek nesnelerin benzersiz key
adları
uygulama veya kitaplık. Örneğin, beş farklı RecyclerView içeren bir uygulama
yerine, her biri için tanımlanabilir anahtarlar sağlamak istiyorsanız
Her biri için RecyclerView
ve ayrıntılı bir şekilde
çerçeve verilerinin işaret ettiği
örnek verilerin elde edilmesini sağlar.
Jank buluşsal yöntemler
Nelerin olumsuz olduğunu belirlemek üzere dahili algoritmayı ayarlamak için
jankHeuristicMultiplier
özelliği.
Sistem jank'ı, varsayılan olarak oluşturulması gerekenden iki kat daha uzun süren bir kare olarak tanımlar. güncel yenileme hızına ayarlanır. Saldırıyı uygulama oluşturma süresiyle ilgili bilgiler tamamen olmadığı için yenileme hızı açık. Bu nedenle, tampon ve yalnızca rapor eklemek daha iyidir sorunlara yol açabilir.
Bu değerlerin her ikisi de söz konusu yöntemler kullanılarak duruma uygun şekilde değiştirilebilir. veya olumsuz yönde etkilemek ya da olumsuz yönde etkilemek gereklidir.
Jetpack Compose'da kullanım
Şu an için Compose'da JankStats'ın kullanılması gereken kurulum işlemi yoktur.
Yapılandırma değişiklikleri genelinde PerformanceMetricsState
özelliğini korumak için
şu şekilde hatırlayın:
/**
* Retrieve MetricsStateHolder from compose and remember until the current view changes.
*/
@Composable
fun rememberMetricsStateHolder(): PerformanceMetricsState.Holder {
val view = LocalView.current
return remember(view) { PerformanceMetricsState.getHolderForHierarchy(view) }
}
JankStats'ı kullanmak için de mevcut durumu stateHolder
öğesine aşağıda gösterildiği gibi ekleyin:
val metricsStateHolder = rememberMetricsStateHolder()
// Reporting scrolling state from compose should be done from side effect to prevent recomposition.
LaunchedEffect(metricsStateHolder, listState) {
snapshotFlow { listState.isScrollInProgress }.collect { isScrolling ->
if (isScrolling) {
metricsStateHolder.state?.putState("LazyList", "Scrolling")
} else {
metricsStateHolder.state?.removeState("LazyList")
}
}
}
Jetpack Compose uygulamanızda JankStats kullanmayla ilgili tüm ayrıntılar için performans örnek uygulamamızı inceleyin.
Geri bildirim gönder
Aşağıdaki kaynakları kullanarak geri bildiriminizi ve düşüncelerinizi bizimle paylaşın:
- Sorun izleyici
- Hataları düzeltebilmemiz için sorunları bildirin. ziyaret edin.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Temel Profiller Oluşturma {:#create-profile-rules}
- Mikro Karşılaştırma Aracı Bağımsız Değişkenleri
- Macrobenchmark Enstrümantasyon Bağımsız Değişkenleri