जैंकस्टैट्स लाइब्रेरी

JamkStats लाइब्रेरी से आपको अपनी परफ़ॉर्मेंस से जुड़ी समस्याओं को ट्रैक और उनका विश्लेषण करने में मदद मिलती है का इस्तेमाल करें. जैंक ऐसे ऐप्लिकेशन फ़्रेम के बारे में बताता है जिन्हें रेंडर होने में बहुत ज़्यादा समय लगता है, और JakStats लाइब्रेरी से आपके ऐप्लिकेशन के जैंक आंकड़ों की रिपोर्ट देखी जा सकती हैं.

क्षमताएं

ZakStats में Android प्लैटफ़ॉर्म की मौजूदा सुविधाएं शामिल हैं. जैसे: FrameMetrics API Android 7 (एपीआई लेवल 24) और उसके बाद के वर्शन या इससे पहले के वर्शन में OnPreDrawListener पर वर्शन हैं. ये तरीके, ऐप्लिकेशन को यह ट्रैक करने में मदद कर सकते हैं कि फ़्रेम को कितने समय में पूरा हुआ. जैंक्सस्टैट्स लाइब्रेरी में दो और भी सुविधाएँ हैं, जो इसे ज़्यादा डाइनैमिक और इस्तेमाल में आसान: जैंक अनुभव और यूज़र इंटरफ़ेस (यूआई) स्थिति.

जैंक ह्यूरिस्टिक्स

फ़्रेम की अवधि ट्रैक करने के लिए, FrameMetrics का इस्तेमाल किया जा सकता है, लेकिन FrameMetrics ये काम नहीं करते को सही जैंक का पता लगाने में कोई मदद चाहिए. हालांकि, जैंकस्टैट्स ने जैंक कब होता है यह तय करने के लिए कॉन्फ़िगर की जा सकने वाली इंटरनल मैकेनिज़्म, ज़्यादा उपयोगी हो जाती है.

यूज़र इंटरफ़ेस (यूआई) की स्थिति

अपने ऐप्लिकेशन में परफ़ॉर्मेंस से जुड़ी समस्याओं का संदर्भ जानना अक्सर ज़रूरी होता है. उदाहरण के लिए, अगर आपने कोई जटिल मल्टी-स्क्रीन ऐप्लिकेशन बनाया है, जो FrameMetrics का इस्तेमाल करता है और आपको पता चलता है कि आपके ऐप्लिकेशन में अक्सर बहुत ही खराब फ़्रेम होते हैं, तो यह जानकर कि समस्या कहां हुई, और उस समस्या के बारे में और उसे दोहराने का तरीका भी है.

JakStats एक ऐसा state एपीआई उपलब्ध कराता है जो इस समस्या को हल करता है. इससे आपको यह काम करने में मदद मिलती है ऐप्लिकेशन में की गई गतिविधि के बारे में जानकारी देने के लिए, लाइब्रेरी से संपर्क किया जा सकता है. टास्क कब शुरू होगा JakStats एक अजीब फ़्रेम के बारे में जानकारी लॉग करता है, इसमें जैंक रिपोर्ट में ऐप्लिकेशन.

इस्तेमाल

JakStats का इस्तेमाल शुरू करने के लिए, हर एक के लिए लाइब्रेरी को इंस्टैंशिएट और चालू करें Window. JakStats का हर ऑब्जेक्ट, डेटा को ट्रैक करता है सिर्फ़ Window में. लाइब्रेरी को चालू करने के लिए, Window इंस्टेंस की ज़रूरत है OnFrameListener के साथ लिसनर, इन दोनों का इस्तेमाल क्लाइंट को मेट्रिक भेजने के लिए किया जाता है. सुनने वाले को यह कॉल किया जाता है: हर फ़्रेम पर FrameData और विवरण के साथ:

  • फ़्रेम शुरू होने का समय
  • अवधि की वैल्यू
  • फ़्रेम को जैंक माना जाना चाहिए या नहीं
  • स्ट्रिंग पेयर का एक सेट जिसमें ऐप्लिकेशन की स्थिति के बारे में जानकारी होती है फ़्रेम के दौरान

ZakStats को ज़्यादा उपयोगी बनाने के लिए, ऐप्लिकेशन को लाइब्रेरी को इस आधार पर पॉप्युलेट करना चाहिए: FrameData में रिपोर्टिंग के लिए, यूज़र इंटरफ़ेस (यूआई) की सही स्थिति की जानकारी. आप यह कर सकते हैं से PerformanceMetricsState एपीआई (सीधे तौर पर JakStats नहीं). इसमें सभी स्टेट मैनेजमेंट लॉजिक और एपीआई लाइव.

प्रोसेस शुरू करना

JakStats लाइब्रेरी का इस्तेमाल शुरू करने के लिए, पहले आपको अपने Gradle फ़ाइल:

implementation "androidx.metrics:metrics-performance:1.0.0-beta01"

इसके बाद, हर Window के लिए JakStats शुरू और चालू करें. आपको रुकना भी चाहिए किसी गतिविधि के बैकग्राउंड में जाने पर, JamkStats की गतिविधि को ट्रैक करना. बनाएं और चालू करें आपकी ऐक्टिविटी में JakStats ऑब्जेक्ट ओवरराइड करता है:

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)
        // ...
    }

ऊपर दिया गया उदाहरण मौजूदा JakStats ऑब्जेक्ट बनाने के बाद होने वाली गतिविधि. आने वाले समय की सभी FrameData रिपोर्ट इस JakStats ऑब्जेक्ट के लिए बनाए गए बनाए गए में अब गतिविधि की जानकारी भी शामिल है.

JankStats.createAndTrack तरीका, Window का रेफ़रंस लेता है ऑब्जेक्ट है, जो उस Window में व्यू हैरारकी के लिए प्रॉक्सी है. Window के लिए. jankFrameListener को उसी थ्रेड पर कॉल किया गया है जिसका इस्तेमाल किया गया है उस जानकारी को प्लैटफ़ॉर्म से JamkStats तक भेजने के लिए किया जा सकता है.

किसी भी JankStats ऑब्जेक्ट पर ट्रैकिंग और रिपोर्टिंग की सुविधा चालू करने के लिए, isTrackingEnabled = true को कॉल करें. यह सुविधा डिफ़ॉल्ट रूप से चालू रहती है, लेकिन किसी गतिविधि को रोकने से ट्रैकिंग बंद हो जाती है. ऐसी स्थिति में, ट्रैकिंग से पहले. ट्रैकिंग रोकने के लिए, isTrackingEnabled = false पर कॉल करें.

override fun onResume() {
    super.onResume()
    jankStats.isTrackingEnabled = true
}

override fun onPause() {
    super.onPause()
    jankStats.isTrackingEnabled = false
}

रिपोर्टिंग

JakStats लाइब्रेरी आपके सारे डेटा की ट्रैकिंग, हर फ़्रेम के लिए, OnFrameListener चालू KankStats ऑब्जेक्ट के लिए. ऐप्लिकेशन, डेटा को सेव और इकट्ठा कर सकते हैं बाद में अपलोड करने के लिए डेटा. ज़्यादा जानकारी के लिए, एग्रीगेशन सेक्शन में दिए गए उदाहरण देखें.

आपको OnFrameListener बनाकर, उपलब्ध कराना होगा, ताकि आपका ऐप्लिकेशन डाउनलोड कर सके की रिपोर्ट देख सकते हैं. इस लिसनर को हर फ़्रेम पर, मौजूदा प्रॉडक्ट उपलब्ध कराने के लिए कॉल किया जाता है ऐप्लिकेशन को डेटा जैंक करने लगता है.

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())
}

लिसनर, जैंक के बारे में हर फ़्रेम के हिसाब से जानकारी देता है. FrameData ऑब्जेक्ट. यह इसमें अनुरोध किए गए फ़्रेम के बारे में यह जानकारी शामिल है:

  • isjank: यह एक बूलियन फ़्लैग है, जो बताता है कि फ़्रेम में जैंक हुआ है या नहीं.
  • frameDurationUiNanos: फ़्रेम की अवधि (नैनोसेकंड में).
  • frameStartNanos: फ़्रेम शुरू होने का समय (नैनोसेकंड में).
  • states: फ़्रेम के दौरान आपके ऐप्लिकेशन की स्थिति.

अगर आपके डिवाइस में Android 12 (एपीआई लेवल 31) या उसके बाद का वर्शन है, तो फ़्रेम अवधि के बारे में ज़्यादा डेटा दिखाने के लिए इनका इस्तेमाल करें:

  • FrameDataApi24 frameDurationCpuNanos से उपलब्ध होता है फ़्रेम के गैर-जीपीयू हिस्सों में बिताया गया समय दिखाने के लिए.
  • FrameDataApi31 frameOverrunNanos से उपलब्ध होता है फ़्रेम के लिए तय की गई समयसीमा के बाद, फ़्रेम में लगने वाला समय दिखाने के लिए पूरा हुआ.

StateInfo का इस्तेमाल लिसनर जो ऐप्लिकेशन की स्थिति के बारे में जानकारी स्टोर करते हैं.

ध्यान दें कि OnFrameListener को उसी थ्रेड पर कॉल किया जाता है जिसका इस्तेमाल अंदरूनी तौर पर किया जाता है JakStats को हर फ़्रेम की जानकारी डिलीवर करेगा. Android वर्शन 6 (एपीआई लेवल 23) और इससे पहले के वर्शन पर, यह मुख्य (यूआई) थ्रेड होता है. Android 7 (एपीआई लेवल 24) और इसके बाद के वर्शन पर, फ़्रेम मेट्रिक के लिए बनाया गया और उसका इस्तेमाल किया गया थ्रेड. दोनों ही मामलों में, यह ज़रूरी है कि कॉलबैक को हैंडल करें और परफ़ॉर्मेंस से जुड़ी समस्याओं से बचने के लिए, इस उस थ्रेड को हटा दिया.

साथ ही, ध्यान दें कि कॉलबैक में भेजे गए FrameData ऑब्जेक्ट का, हर फ़्रेम का इस्तेमाल करें. इसका मतलब है कि आपको उस डेटा को कहीं और कॉपी और कैश मेमोरी में सेव करना होगा, क्योंकि उस ऑब्जेक्ट को कॉलबैक के वापस आने पर, स्टेटल और पुराना हो जाता है.

इकट्ठा किया जा रहा है

हो सकता है आप चाहें कि आपका ऐप्लिकेशन कोड हर फ़्रेम का डेटा इकट्ठा करे, जिससे आपको अपने विवेक से जानकारी को सेव और अपलोड करना होगा. हालांकि, ब्यौरे सेव करने और अपलोड करने से जुड़ी सुविधाएं, ऐल्फ़ा JakStats API के दायरे से बाहर हैं रिलीज़ के बाद, हर फ़्रेम के डेटा को इकट्ठा करने के लिए, शुरुआती गतिविधि देखी जा सकती है एक बड़े संग्रह में बदल सकते हैं. इसके लिए, यह JankAggregatorActivity का इस्तेमाल करें. GitHub का डेटा स्टोर करने की जगह.

JankAggregatorActivity अपनी रिपोर्टिंग की लेयर बनाने के लिए, JankStatsAggregator क्लास का इस्तेमाल करता है JakStats OnFrameListener तकनीक की मदद से एक ऐसी तकनीक बनाई गई है. सिर्फ़ ऐसी जानकारी के कलेक्शन की रिपोर्टिंग के लिए, जो उच्च स्तर का ऐब्स्ट्रैक्ट है कई फ़्रेम में फैला होता है.

सीधे JakStats ऑब्जेक्ट बनाने के बजाय, JankAggregatorActivity यह एक jankStatsAgregator बनाता है ऑब्जेक्ट देता है, जो आंतरिक रूप से अपना JkStats ऑब्जेक्ट बनाता है:

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 में एक मिलते-जुलते तरीके का इस्तेमाल किया गया है समस्या के सिग्नल के तौर पर pause() इवेंट को जोड़कर, ट्रैकिंग फिर से शुरू करें एक रिपोर्ट जिसमें issueJankReport() को कॉल किया गया हो, क्योंकि लाइफ़साइकल में हुए बदलाव ऐप्लिकेशन में जैंक की स्थिति कैप्चर करने के लिए सही समय:

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
}

ऊपर दिए गए उदाहरण में वे सभी कोड हैं जिनकी ज़रूरत किसी ऐप्लिकेशन को JakStats चालू करने और पाने के लिए होती है फ़्रेम डेटा.

राज्य मैनेज करें

यह संभव है कि आप JakStats को कस्टमाइज़ करने के लिए अन्य API को कॉल करना चाहें. इसके लिए उदाहरण के लिए, ऐप्लिकेशन की स्थिति की जानकारी इंजेक्ट करने से फ़्रेम डेटा, उन फ़्रेम के लिए संदर्भ उपलब्ध कराती है जिनमें जैंक होता है.

यह स्टैटिक तरीका मौजूदा MetricsStateHolder ऑब्जेक्ट है.

PerformanceMetricsState.getHolderForHierarchy(view: View): MetricsStateHolder

मौजूदा हैरारकी में किसी भी व्यू का इस्तेमाल किया जा सकता है. इंटरनल तौर पर, यह देखता है कि क्या उससे कोई मौजूदा Holder ऑब्जेक्ट जुड़ा हुआ है देखें. यह जानकारी सबसे ऊपर मौजूद व्यू में कैश मेमोरी में सेव होती है हैरारकी है. अगर ऐसा कोई ऑब्जेक्ट मौजूद नहीं है, तो getHolderForHierarchy() एक ऑब्जेक्ट बनाता है.

स्टैटिक getHolderForHierarchy() तरीके से, आपको कैश मेमोरी में सेव होने से बचने में मदद मिलती है होल्डर के इंस्टेंस में कहीं भी मौजूद हो, ताकि उसे बाद में वापस पाया जा सके. साथ ही, इससे उसे वापस पाने में आसानी होती है किसी मौजूदा स्थिति ऑब्जेक्ट को कोड (या लाइब्रेरी कोड में भी, जिसे ऐसा न होने पर, ओरिजनल इंस्टेंस का ऐक्सेस नहीं होता).

ध्यान दें कि रिटर्न वैल्यू, होल्डर ऑब्जेक्ट है, न कि स्टेट ऑब्जेक्ट. कॉन्टेंट बनाने होल्डर के अंदर स्टेट ऑब्जेक्ट का मान सिर्फ़ JankStats के ज़रिए सेट किया जाता है. वह है, अगर कोई ऐप्लिकेशन उस विंडो के लिए JakStats ऑब्जेक्ट बनाता है जिसमें वह मौजूद है देखें, तो स्टेट ऑब्जेक्ट यह होगा बनाया और सेट किया. अगर ऐसा नहीं होता है, तो JakStats किसी भी जानकारी को ट्रैक नहीं करता है. स्टेट ऑब्जेक्ट की कोई ज़रूरत नहीं है. साथ ही, ऐप्लिकेशन या लाइब्रेरी के लिए यह ज़रूरी नहीं है कोड डालने की ज़रूरत नहीं होती.

इस तरीके से, हम इन कामों को कर पाते हैं उसके बाद, आपके पास एक ऐसा होल्डर है जिसे जापान के जेंकस्टैट बाहरी कोड रखने वाले से किसी भी समय अनुरोध किया जा सकता है. कॉलर, लाइटवेट Holder को कैश मेमोरी में सेव कर सकते हैं ऑब्जेक्ट के मान के आधार पर, उसकी स्थिति सेट करने के लिए किसी भी समय उसका इस्तेमाल करें इंटरनल state प्रॉपर्टी, जैसा कि नीचे उदाहरण में दिया गया है, जहां राज्य सिर्फ़ सेट है जब मालिक के इंटरनल स्टेट प्रॉपर्टी शून्य नहीं होती है:

val metricsStateHolder = PerformanceMetricsState.getHolderForHierarchy(binding.root)
// ...
metricsStateHolder.state?.putState("Activity", javaClass.simpleName)

यूज़र इंटरफ़ेस (यूआई) या ऐप्लिकेशन की स्थिति को कंट्रोल करने के लिए, ऐप्लिकेशन किसी स्थिति को इंजेक्ट कर सकता है या हटा सकता है putState और removeState तरीकों का इस्तेमाल करें. ZakStats, इस चीज़ का टाइमस्टैंप लॉग करता है ये कॉल करते हैं. अगर कोई फ़्रेम, स्टेट के शुरू और खत्म होने के समय को ओवरलैप करता है, ZakStats की रिपोर्ट में उस रिपोर्ट के लिए समय के डेटा के साथ-साथ जानकारी फ़्रेम.

किसी भी राज्य के लिए, दो तरह की जानकारी जोड़ें: key (राज्य की एक कैटगरी, जैसे कि “RecyclerView”) और value ( उस समय क्या हो रहा था, जैसे कि “स्क्रोल करना”).

अगर यह स्थिति कोई नहीं है, तो removeState() तरीके का इस्तेमाल करके स्थितियां हटाएं लंबे समय तक मान्य हो, ताकि यह पक्का किया जा सके कि गलत या गुमराह करने वाली जानकारी की शिकायत नहीं की जाती के साथ किया जाता है.

पहले जोड़े गए key के साथ putState() को कॉल करने से, यह नए राज्य के साथ उस राज्य का value मौजूदा

स्टेट एपीआई के putSingleFrameState() वर्शन में ऐसा स्टेटस जोड़ा जाता है जो रिपोर्ट किए जाने वाले अगले फ़्रेम पर, सिर्फ़ एक बार लॉग किया गया. सिस्टम अपने-आप इसके बाद उसे हटा देता है, ताकि आप अनजाने में अपनी आपका कोड. ध्यान दें कि इसके बराबर कोई सिंगलFrame नहीं है removeState(), क्योंकि JohnkStats पर एक फ़्रेम वाली स्थितियां अपने-आप हट जाती हैं.

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")
            }
        }
    }
}

ध्यान दें कि राज्यों के लिए इस्तेमाल की जाने वाली कुंजी इतनी खराब होनी चाहिए कि बाद में किया जा सकता है. खास तौर पर, क्योंकि एक ही key वाले राज्य से को पहले जोड़ा गया था, तो वह उस पिछले मान को बदल देगा, तो आपको उन ऑब्जेक्ट के लिए यूनीक key नाम जिनके लिए, आपके आइटम में अलग-अलग इंस्टेंस हो सकते हैं ऐप या लाइब्रेरी में सेव किया गया है. उदाहरण के लिए, पांच अलग-अलग RecyclerViews वाले ऐप्लिकेशन में में से हर एक के लिए, पहचानी जा सकने वाली कुंजियां उपलब्ध कराना हर एक के लिए RecyclerView और फिर आपको से मिलने वाला डेटा, जिससे फ़्रेम डेटा का इंस्टेंस जुड़ा होता है.

जैंक ह्यूरिस्टिक्स

इंटरनल एल्गोरिदम में बदलाव करने के लिए, यह तय करें कि किस तरह के एल्गोरिदम को जैंक माना जाता है. इसके लिए, jankHeuristicMultiplier प्रॉपर्टी.

डिफ़ॉल्ट रूप से, सिस्टम जैंक को एक फ़्रेम के रूप में परिभाषित करता है, जो मौजूदा रीफ़्रेश दर. यह जैंक को रीफ़्रेश दर की वजह से, ऐप्लिकेशन को रेंडर होने में लगने वाले समय की जानकारी पूरी तरह से नहीं मिलती हटाएं. इसलिए, बफ़र और सिर्फ़ रिपोर्ट जोड़ना बेहतर माना जाता है समस्याओं को ठीक करना न भूलें.

स्थिति के हिसाब से, इन दोनों वैल्यू में बदलाव किया जा सकता है या जैंक होने या न होने के लिए ज़बरदस्ती करने के लिए, ऐप्लिकेशन के इस्तेमाल को लेकर टेस्ट के लिए ज़रूरी है.

Jetpack Compose में इस्तेमाल

फ़िलहाल, Compose में JamkStats का इस्तेमाल करने के लिए बहुत कम सेटअप की ज़रूरत है. कॉन्फ़िगरेशन में हुए सभी बदलावों के लिए, PerformanceMetricsState पर बने रहने के लिए, इसे ऐसे याद रखो:

/**
 * 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) }
}

और JakStats का इस्तेमाल करने के लिए, मौजूदा स्थिति को stateHolder में जोड़ें जैसा कि यहां दिखाया गया है:

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 ऐप्लिकेशन में JakStats इस्तेमाल करने के बारे में पूरी जानकारी के लिए देखें. परफ़ॉर्मेंस सैंपल ऐप्लिकेशन को आज़माएं.

सुझाव या राय दें

इन संसाधनों की मदद से, हमारे साथ अपने सुझाव, शिकायत या राय शेयर करें:

समस्या को ट्रैक करने वाला टूल
समस्याओं की शिकायत करें, ताकि हम गड़बड़ियां ठीक कर सकें.