MessageQueue के व्यवहार में बदलाव से जुड़े दिशा-निर्देश

Android 17 से, Android 17 (एपीआई लेवल 37) या इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन को android.os.MessageQueue का नया लॉक-फ़्री वर्शन मिलता है. इस नई सुविधा को लागू करने से, परफ़ॉर्मेंस बेहतर होती है और छूटे हुए फ़्रेम की संख्या कम होती है. हालांकि, इससे उन क्लाइंट पर असर पड़ सकता है जो MessageQueue निजी फ़ील्ड और तरीकों को दिखाते हैं.

Android 17 में, Looper और Handler के काम करने के तरीके में काफ़ी बदलाव किया गया है. इसके लिए, MessageQueue क्लास को फिर से लिखा गया है. Android ऑपरेटिंग सिस्टम की पहली रिलीज़ के बाद से, MessageQueue मुख्य थ्रेड की टास्क कतार को मैनेज करने के लिए, एक ही लॉक पर निर्भर था. इस डिज़ाइन की वजह से अक्सर लॉक कंटेंशन की समस्या होती थी. बैकग्राउंड थ्रेड की वजह से मुख्य थ्रेड ब्लॉक हो सकती थी. इससे फ़्रेम ड्रॉप होते थे और यूज़र इंटरफ़ेस (यूआई) में रुकावट आती थी.

असर कम करना

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

लेगसी वर्शन में, डेवलपर कभी-कभी निजी फ़ील्ड (जैसे, MessageQueue.mMessages) को ऐक्सेस करते थे, ताकि वे ऐसे मैसेज की जांच कर सकें जिन्हें अभी तक प्रोसेस नहीं किया गया है. लॉक-फ़्री सुविधा के नए वर्शन में, इंटरनल डेटा स्ट्रक्चर पूरी तरह से बदल गए हैं. बाइनरी के साथ काम करने की सुविधा को बनाए रखने के लिए, Android 17 में mMessages फ़ील्ड को बनाए रखा गया है. हालांकि, नए तरीके से लागू करने पर यह फ़ील्ड हमेशा शून्य होता है. इससे कोई फ़र्क़ नहीं पड़ता कि कतार में मैसेज हैं या नहीं.

इसके अलावा, अगर टेस्टिंग के लिए कुछ लोकप्रिय लाइब्रेरी का इस्तेमाल किया जाता है, तो आपको अपनी लाइब्रेरी अपडेट करनी होंगी, ताकि वे MessageQueue के नए वर्शन के साथ काम कर सकें.

एस्प्रेसो

Espresso का इस्तेमाल आम तौर पर यूज़र इंटरफ़ेस (यूआई) की जांच के लिए किया जाता है. Espresso लाइब्रेरी को यह पता होना चाहिए कि मुख्य थ्रेड कब निष्क्रिय है, ताकि यूज़र इंटरफ़ेस (यूआई) की स्थिति की पुष्टि सही तरीके से की जा सके. Espresso के पुराने वर्शन, रिफ़्लेक्शन तकनीकों पर निर्भर करते थे. ये तकनीकें, अब लॉक-फ़्री MessageQueue के साथ काम नहीं करती हैं.

कार्रवाई

Espresso 3.7.0 या इसके बाद के वर्शन पर अपडेट करें. यह वर्शन, TestLooperManager एपीआई का इस्तेमाल करता है. खास तौर पर, Android 16 में पेश किए गए नए एपीआई का इस्तेमाल करता है. इससे, इंटरनल इंप्लीमेंटेशन की जानकारी पर भरोसा किए बिना, Looper के साथ सुरक्षित तरीके से इंटरैक्ट किया जा सकता है.

Robolectric

इसी तरह, अगर Robolectric का इस्तेमाल करके यूनिट टेस्ट किए जाते हैं, तो आपको समस्याएं आ सकती हैं. ऐसा तब होता है, जब आपके टेस्ट लेगसी लूपर मोड पर निर्भर होते हैं.

कार्रवाई

Robolectric 4.17 या इसके बाद के वर्शन पर अपडेट करें. अगर @LooperMode(LEGACY) का इस्तेमाल किया जा रहा है, तो आपको अपने टेस्ट को नए @LooperMode(PAUSED) पर माइग्रेट करना होगा. ज़्यादा जानकारी के लिए, Robolectric की माइग्रेशन गाइड देखें.

व्यवहार की जांच करना

Android 17 पर, ऐप्लिकेशन के व्यवहार में हुए बदलाव को टेस्ट किया जा सकता है. इसके लिए, targetSDK को अपडेट करने की ज़रूरत नहीं है. इसके लिए, यहां दी गई कमांड का इस्तेमाल करें:

adb am compat enable USE_NEW_MESSAGEQUEUE <your-package-name>

अगर आपका ऐप्लिकेशन डीबग किया जा सकने वाला बिल्ड है, तो यह कमांड आपके ऐप्लिकेशन में लॉक-फ़्री MessageQueue को चालू करती है.

अगर आपका ऐप्लिकेशन, Android 17 (एपीआई लेवल 37) को टारगेट करता है, तो यह नई सुविधा डिफ़ॉल्ट रूप से चालू होती है. अगर आपको इस एपीआई लेवल को टारगेट करने के बाद, ऐप्लिकेशन में कोई गड़बड़ी दिखती है या वह क्रैश हो जाता है, तो कुछ समय के लिए नए बदलाव को बंद करें. इससे यह पुष्टि की जा सकेगी कि MessageQueue की वजह से ऐसा हो रहा है या नहीं.

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

  1. ऐप्लिकेशन के साथ काम करने के लिए किए गए बदलाव मेन्यू में डेवलपर के लिए सेटिंग और टूल.

  2. ADB के इस कमांड को चलाकर:

    adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
    

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