ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करने के लिए, आपको ऐसी लाइब्रेरी इस्तेमाल करनी होंगी जो Android ऑप्टिमाइज़ेशन के साथ काम करती हों. अगर किसी लाइब्रेरी को Android ऑप्टिमाइज़ेशन के लिए कॉन्फ़िगर नहीं किया गया है, तो हो सकता है कि वह Android ऐप्लिकेशन के लिए सही न हो. उदाहरण के लिए, अगर वह लाइब्रेरी, Keep से जुड़े नियमों को बंडल किए बिना reflection का इस्तेमाल करती है. इस पेज पर बताया गया है कि कुछ लाइब्रेरी, ऐप्लिकेशन ऑप्टिमाइज़ेशन के लिए बेहतर क्यों होती हैं. साथ ही, आपको लाइब्रेरी चुनने में मदद करने के लिए सामान्य सुझाव दिए गए हैं.
लाइब्रेरी चुनते समय काम आने वाली सामान्य सलाह
इन सुझावों का इस्तेमाल करके, यह पक्का करें कि आपकी लाइब्रेरी, ऐप्लिकेशन ऑप्टिमाइज़ेशन के साथ काम करती हैं.
रिफ़्लेक्शन के बजाय कोड जनरेशन को प्राथमिकता दें
ऐसी लाइब्रेरी चुनें जो रिफ़्लेक्शन के बजाय कोड जनरेशन (codegen) का इस्तेमाल करती हैं. कोड जनरेशन की मदद से, ऑप्टिमाइज़र यह तय कर सकता है कि रनटाइम के दौरान कौनसा कोड इस्तेमाल किया जाता है और कौनसा कोड हटाया जा सकता है. यह पता लगाना मुश्किल हो सकता है कि कोई लाइब्रेरी कोडजन या रिफ़्लेक्शन का इस्तेमाल करती है या नहीं. हालांकि, इसके कुछ संकेत होते हैं. मदद पाने के लिए, सलाह देखें.
कोड जनरेशन बनाम रिफ़्लेक्शन के बारे में ज़्यादा जानने के लिए, लाइब्रेरी तैयार करने वालों के लिए ऑप्टिमाइज़ेशन लेख पढ़ें.
रिफ़्लेक्शन (ऐडवांस) के इस्तेमाल की जांच करना
किसी लाइब्रेरी के कोड की जांच करके, यह पता लगाया जा सकता है कि वह रिफ़्लेक्शन का इस्तेमाल करती है या नहीं. अगर लाइब्रेरी रिफ़्लेक्शन का इस्तेमाल करती है, तो पक्का करें कि वह डेटा बनाए रखने के नियमों से जुड़ी जानकारी देती हो. अगर कोई लाइब्रेरी ये काम करती है, तो हो सकता है कि वह रिफ़्लेक्शन का इस्तेमाल करती हो:
kotlin.reflectयाjava.lang.reflectपैकेज की क्लास या तरीकों का इस्तेमाल करता है.Class.forNameयाclassLoader.getClassफ़ंक्शन का इस्तेमाल करता है.- यह रनटाइम के दौरान एनोटेशन पढ़ता है. उदाहरण के लिए, अगर यह
val value = myClass.getAnnotation()याval value = myMethod.getAnnotation()का इस्तेमाल करके एनोटेशन वैल्यू सेव करता है और फिरvalueके साथ कुछ करता है. इस तरीके से, किसी तरीके को कॉल करने के लिए, तरीके के नाम का इस्तेमाल स्ट्रिंग के तौर पर किया जाता है. जैसे, यहां दिए गए उदाहरण में:
// Calls the private `processData` API with reflection myObject.javaClass.getMethod("processData", DataType::class.java) ?.invoke(myObject, data)
ऑप्टिमाइज़ेशन से जुड़ी समस्याओं की जांच करना
नई लाइब्रेरी का इस्तेमाल करने से पहले, लाइब्रेरी के इश्यू ट्रैकर और ऑनलाइन चर्चाओं को देखें. इससे आपको यह पता चलेगा कि क्या लाइब्रेरी में, कोड छोटा करने या ऐप्लिकेशन ऑप्टिमाइज़ेशन को कॉन्फ़िगर करने से जुड़ी समस्याएं हैं. अगर ऐसा है, तो आपको उस लाइब्रेरी के विकल्पों को ढूंढना चाहिए. इन बातों का ध्यान रखें:
- AndroidX लाइब्रेरी और Hilt जैसी लाइब्रेरी, ऐप्लिकेशन ऑप्टिमाइज़ेशन के साथ अच्छी तरह से काम करती हैं. इसकी वजह यह है कि ये ज़्यादातर रिफ़्लेक्शन के बजाय कोडजन का इस्तेमाल करती हैं. जब वे रिफ़्लेक्शन का इस्तेमाल करते हैं, तो वे सिर्फ़ ज़रूरी कोड को बनाए रखने के लिए, कम से कम नियमों का पालन करते हैं.
- सीरियलाइज़ेशन लाइब्रेरी, ऑब्जेक्ट को इंस्टैंटिएट या सीरियलाइज़ करते समय, अक्सर रिफ़्लेक्शन का इस्तेमाल करती हैं. इससे उन्हें बॉयलरप्लेट कोड से बचने में मदद मिलती है. रिफ़्लेक्शन पर आधारित तरीकों (जैसे, JSON के लिए Gson) के बजाय, ऐसी लाइब्रेरी खोजें जो इन समस्याओं से बचने के लिए कोड जनरेशन का इस्तेमाल करती हैं. उदाहरण के लिए, Kotlin Serialization या कोड जनरेशन के साथ Moshi का इस्तेमाल करें.
- अगर हो सके, तो ऐसी लाइब्रेरी का इस्तेमाल न करें जिनमें पैकेज के लिए, डेटा सुरक्षित रखने के नियम शामिल हों. पैकेज के हिसाब से डेटा बनाए रखने के नियमों से गड़बड़ियों को ठीक करने में मदद मिल सकती है. हालांकि, डेटा बनाए रखने के सामान्य नियमों को आखिर में बेहतर बनाया जाना चाहिए, ताकि सिर्फ़ ज़रूरी कोड को बनाए रखा जा सके. ज़्यादा जानकारी के लिए, ऑप्टिमाइज़ेशन को धीरे-धीरे लागू करना लेख पढ़ें.
- तीसरे पक्ष की लाइब्रेरी का इस्तेमाल करने वाले ऐप्लिकेशन को पब्लिश करने से पहले, R8 कॉन्फ़िगरेशन ऐनलिसिस टूल का इस्तेमाल करके, लाइब्रेरी के 'कीप रूल' की जांच करें. रिपोर्ट की समीक्षा करके, आप यह पुष्टि कर सकते हैं कि लाइब्रेरी के कीप नियमों का दायरा बहुत बड़ा तो नहीं है. ऐसा होने पर, R8 आपके कोड बेस पर ज़रूरी ऑप्टिमाइज़ेशन नहीं कर पाता है. इस जांच से यह पक्का किया जाता है कि चुनी गई लाइब्रेरी, आपके ऐप्लिकेशन की परफ़ॉर्मेंस के लक्ष्यों के मुताबिक हों. साथ ही, उनसे कॉन्फ़िगरेशन में ज़रूरत से ज़्यादा डेटा न जुड़े.
- लाइब्रेरी को, दस्तावेज़ से कीप नियमों को कॉपी करके अपने प्रोजेक्ट की किसी फ़ाइल में चिपकाने की ज़रूरत नहीं होनी चाहिए. खास तौर पर, पैकेज-वाइड कीप नियमों को कॉपी करके चिपकाने की ज़रूरत नहीं होनी चाहिए. इन नियमों को लंबे समय तक बनाए रखना, ऐप्लिकेशन डेवलपर के लिए मुश्किल होता है. साथ ही, समय के साथ इन्हें ऑप्टिमाइज़ करना और बदलना भी मुश्किल होता है.
नई लाइब्रेरी जोड़ने के बाद ऑप्टिमाइज़ेशन की सुविधा चालू करना
नई लाइब्रेरी जोड़ने के बाद, ऑप्टिमाइज़ेशन की सुविधा चालू करें. साथ ही, देखें कि कोई गड़बड़ी तो नहीं है. अगर कोई गड़बड़ी है, तो उस लाइब्रेरी के विकल्प ढूंढें या नियमों को बनाए रखें. अगर कोई लाइब्रेरी ऑप्टिमाइज़ेशन के साथ काम नहीं करती है, तो उस लाइब्रेरी के साथ गड़बड़ी की शिकायत करें.
खराब कीप नियमों को फ़िल्टर करना (ऐडवांस)
Keep नियमों को जोड़ा जाता है. इसका मतलब है कि लाइब्रेरी डिपेंडेंसी में शामिल कुछ नियमों को हटाया नहीं जा सकता. साथ ही, ये नियम आपके ऐप्लिकेशन के अन्य हिस्सों के कंपाइलेशन पर असर डाल सकते हैं. उदाहरण के लिए, अगर किसी लाइब्रेरी में कोड ऑप्टिमाइज़ेशन को बंद करने का नियम शामिल है, तो यह नियम आपके पूरे प्रोजेक्ट के लिए ऑप्टिमाइज़ेशन को बंद कर देता है.
आपको ऐसी लाइब्रेरी का इस्तेमाल नहीं करना चाहिए जिनमें कोड को बनाए रखने के नियम लागू होते हैं. ऐसा इसलिए, क्योंकि इन नियमों के तहत ऐसे कोड को भी बनाए रखा जाता है जिसे हटा दिया जाना चाहिए. हालांकि, अगर आपको इनका इस्तेमाल करना ही है, तो यहां दिए गए कोड में दिखाए गए तरीके से नियमों को फ़िल्टर किया जा सकता है:
// If you're using AGP 8.4 and higher
buildTypes {
release {
optimization.keepRules {
it.ignoreFrom("com.somelibrary:somelibrary")
}
}
}
// If you're using AGP 7.3-8.3
buildTypes {
release {
optimization.keepRules {
it.ignoreExternalDependencies("com.somelibrary:somelibrary")
}
}
}
केस स्टडी: ऑप्टिमाइज़ेशन के साथ Gson क्यों काम नहीं करता
Gson, एक सीरियलाइज़ेशन लाइब्रेरी है. यह अक्सर ऐप्लिकेशन ऑप्टिमाइज़ेशन से जुड़ी समस्याएं पैदा करती है, क्योंकि यह रिफ़्लेक्शन का ज़्यादा इस्तेमाल करती है. नीचे दिए गए कोड स्निपेट में दिखाया गया है कि Gson का इस्तेमाल आम तौर पर कैसे किया जाता है. इससे रनटाइम के दौरान क्रैश हो सकता है. ध्यान दें कि User ऑब्जेक्ट की सूची पाने के लिए Gson का इस्तेमाल करते समय, कंस्ट्रक्टर को कॉल नहीं किया जाता या fromJson() फ़ंक्शन को फ़ैक्ट्री पास नहीं की जाती. अगर ऐप्लिकेशन में तय की गई क्लास को इन दोनों में से किसी भी तरीके से नहीं बनाया जा रहा है या इस्तेमाल नहीं किया जा रहा है, तो इसका मतलब है कि लाइब्रेरी, ओपन-एंडेड रिफ़्लेक्शन का इस्तेमाल कर रही है:
- लाइब्रेरी, स्टैंडर्ड इंटरफ़ेस या क्लास को लागू करने वाली ऐप्लिकेशन क्लास
- कोड जनरेट करने वाला प्लगिन, जैसे कि KSP
class User(val name: String)
class UserList(val users: List<User>)
// This code runs in debug mode, but crashes when optimizations are enabled
Gson().fromJson("""[{"name":"myname"}]""", User::class.java).toString()
Gson पर R8 के काम करने के तरीके को समझने के लिए, Gson के लिए R8 के नियम देखें. जब R8 इस कोड का विश्लेषण करता है और उसे कहीं भी UserList या User इंस्टैंशिएट नहीं दिखता है, तो वह फ़ील्ड का नाम बदल सकता है या ऐसे कंस्ट्रक्टर हटा सकता है जिनका इस्तेमाल नहीं किया जा रहा है. इससे आपका ऐप्लिकेशन क्रैश हो सकता है. अगर इसी तरह से किसी दूसरी लाइब्रेरी का इस्तेमाल किया जा रहा है, तो आपको यह देखना चाहिए कि वे ऐप्लिकेशन ऑप्टिमाइज़ेशन में रुकावट न डालें. अगर वे रुकावट डालती हैं, तो उनका इस्तेमाल न करें.
Gson के नए वर्शन के साथ @SerializedName का इस्तेमाल करना
Gson के नियमों के मुताबिक अपने डेटा मॉडल तय करने के लिए, अपने फ़ील्ड को @SerializedName से एनोटेट करें. यहां दिए गए स्निपेट में इसका उदाहरण दिखाया गया है:
import com.google.gson.annotations.SerializedName
class User(@SerializedName("name") val name: String)
class UserList(@SerializedName("users") val users: List<User>)
@SerializedName एनोटेशन का इस्तेमाल करके, R8 को अपने मॉडल क्लास को Gson 2.11.0 और इसके बाद के वर्शन में बंडल किए गए keep नियमों से मैच करने की अनुमति दी जाती है.
R8, एनोटेट किए गए फ़ील्ड और ज़रूरी कंस्ट्रक्टर को अपने-आप सुरक्षित रखता है. इससे आपको लाइब्रेरी के बंडल किए गए नियमों पर भरोसा करने में मदद मिलती है. साथ ही, आपको अपने प्रोजेक्ट में ProGuard के कॉन्फ़िगरेशन को मैन्युअल तरीके से बनाए रखने की ज़रूरत नहीं पड़ती.
ध्यान दें कि Room, Hilt, और Moshi with codegen, ऐप्लिकेशन के हिसाब से टाइप बनाते हैं. हालांकि, रिफ़्लेक्शन की ज़रूरत से बचने के लिए, ये codegen का इस्तेमाल करते हैं.