Android SDK ProGuard ऑबफ़स्केशन नियमों को सुरक्षित रूप से कैसे कॉन्फ़िगर करें

opoinstall
2026-11-11
5 min read

मोबाइल SDK को Android ProGuard ऑबफ़स्केशन से कैसे बाहर रखें? किसी Android SDK को ऑबफ़स्केशन (obfuscation) से बाहर रखने के लिए यह सत्यापित करना आवश्यक है कि क्या लाइब्रेरी में कंज़्यूमर ProGuard नियम बंडल किए गए हैं, रिफ्लेक्टिव रूप से एक्सेस किए जाने वाले एंट्री पॉइंट्स, कॉलबैक इंटरफ़ेस, JNI ब्रिज और डेटा मॉडल्स के लिए सटीक रूप से स्कोप किए गए -keep और -keepclassmembers डायरेक्टिव जोड़ना, और R8 डायग्नोस्टिक रिपोर्ट तथा रॉ DEX निरीक्षण के माध्यम से सुरक्षित किए गए सिंबल्स का ऑडिट करना शामिल है। जब Android इंजीनियरिंग टीमें प्रोडक्शन रिलीज़ बिल्ड के लिए कोड श्रिंकिंग (code shrinking) और ऑप्टिमाइज़ेशन सक्षम करती हैं, तो R8 कंपाइलर बिना रेफ़रेंस वाले बाइटकोड को हटा देता है और क्लासेस, फ़ील्ड्स तथा मेथड्स का नाम बदलकर छोटे आइडेंटिफ़ायर रख देता है। यदि कोई मोबाइल एट्रिब्यूशन Software Development Kit (SDK) डायनेमिक रिफ्लेक्शन या JNI कॉलबैक पर निर्भर करता है जो आक्रामक ट्री-शेकिंग (tree-shaking) और रीनेमिंग से सुरक्षित नहीं हैं, तो नॉन-मिनिफ़ाइड डीबग बिल्ड में हर टेस्ट पास करने के बाद भी प्रोडक्शन में deferred deep linking, JSON मॉडल डीसीरियलाइज़ेशन और चैनल-पैकेज बिल्ड चुपचाप विफल हो सकते हैं। OpoInstall, एक मोबाइल एट्रिब्यूशन और deep linking प्लेटफ़ॉर्म, नेटिव Android SDK आर्काइव और चैनल-पैकेज वर्कफ़्लो प्रदान करता है जिन्हें इंजीनियरिंग टीमें R8-मिनिफ़ाइड रिलीज़ पाइपलाइनों के भीतर कॉन्फ़िगर और सत्यापित कर सकती हैं।

आधुनिक Android Gradle Plugin (AGP) टूलचेन में, keep-rule फ़ाइलें (लेगेसी DSL में proguard-rules.pro या AGP 9.3+ में src/<variant>/keepRules/*.keep) Google के R8 कंपाइलर के लिए नियम कॉन्फ़िगरेशन अनुबंध के रूप में कार्य करती हैं। किसी थर्ड-पार्टी Android SDK को ऑबफ़स्केशन से सुरक्षित रूप से बाहर रखने का अर्थ है केवल उन विशिष्ट पब्लिक API एंट्री पॉइंट्स, रिफ्लेक्टिव कंस्ट्रक्टर्स, कॉलबैक इंटरफ़ेस, JNI अपकॉल्स और मॉडल फ़ील्ड्स को सुरक्षित रखना जिनकी रनटाइम पर आवश्यकता होती है—जबकि अत्यधिक व्यापक पैकेज-स्तरीय keep नियमों या असत्यापित चेतावनी दमन (warning suppressions) से बचना चाहिए।

शब्द (Term) परिभाषा संबंधित इकाई सर्च इंटेंट की भूमिका
Android SDK इंस्टॉल एट्रिब्यूशन जैसी विशेष क्षमताएं प्रदान करने के लिए Android App में एकीकृत की गई एक कंपाइल्ड Java या Kotlin लाइब्रेरी। classes.dex बाइटकोड नेविगेशनल / ट्रांज़ैक्शनल
ProGuard / R8 Android बिल्ड-टाइम टूल्स जो ProGuard नियम सिंटैक्स का उपयोग करके अप्रयुक्त कोड को छोटा करते हैं, बाइटकोड को ऑप्टिमाइज़ करते हैं और आइडेंटिफ़ायर को ऑबफ़स्केट करते हैं। proguard-rules.pro तकनीकी / सूचनात्मक
Consumer ProGuard Rules .aar (/proguard.txt) या .jar (/META-INF/proguard/) के अंदर बंडल किए गए ऑबफ़स्केशन नियम जो स्वचालित रूप से R8 में मर्ज हो जाते हैं। consumerProguardFiles तकनीकी / समस्या निवारण
R8 Diagnostic Reports आउटपुट फ़ाइलें (mapping.txt, seeds.txt, usage.txt, configuration.txt) जो सिंबल रीनेमिंग, मैच किए गए keep सीड्स और हटाए गए कोड का विवरण देती हैं। रिलीज़ बिल्ड ऑडिट तकनीकी / समस्या निवारण

R8 और ProGuard ऑबफ़स्केशन Android SDK एट्रिब्यूशन कॉलबैक को क्यों बाधित करता है

Android R8 ऑप्टिमाइज़ेशन रिलीज़ कंपाइलेशन के दौरान आवश्यक SDK सिंबल्स को सुरक्षित रखता है।

डीबग बनाम रिलीज़ का जाल: टेस्टिंग में एट्रिब्यूशन क्यों काम करता है लेकिन प्रोडक्शन में विफल हो जाता है

मोबाइल यूज़र एक्विजिशन में सबसे आम रिलीज़-इंजीनियरिंग समस्याओं में से एक तब होती है जब किसी एप्लिकेशन की deferred deep linking (handleDeepLink) और इंस्टॉल पैरामीटर रीस्टोरेशन (getInstallParam) डीबग बिल्ड पर QA टेस्टिंग के दौरान विश्वसनीय रूप से काम करते हैं, लेकिन एक बार जब App को साइन्ड रिलीज़ APK या Android App Bundle (.aab) के रूप में कंपाइल किया जाता है, तो वे खाली पेलोड लौटाते हैं या कॉलबैक फ़ायर करना बंद कर देते हैं।

इसका मुख्य कारण Gradle में कॉन्फ़िगर की गई बिल्ड-टाइप असमानता में निहित है। डिफ़ॉल्ट रूप से, इंक्रीमेंटल बिल्ड को तेज़ करने के लिए debug बिल्ड टाइप कोड श्रिंकिंग को अक्षम रखता है। जब इंजीनियर R8 ऑप्टिमाइज़ेशन सक्षम करके release वेरिएंट को कंपाइल करते हैं, तो Android Gradle Plugin होस्ट App और लिंक की गई थर्ड-पार्टी लाइब्रेरी दोनों में तीन बाइटकोड परिवर्तनों को निष्पादित करने के लिए Android R8 Compiler को कॉल करता है:

  • Code Shrinking (Tree Shaking): R8 घोषित एंट्री पॉइंट्स (जैसे AndroidManifest.xml कंपोनेंट्स और स्पष्ट -keep सीड्स) से शुरू करके एप्लिकेशन के कॉल ग्राफ़ का विश्लेषण करता है और किसी भी ऐसे क्लास, कंस्ट्रक्टर, मेथड या फ़ील्ड को हटा देता है जो स्टैटिक विश्लेषण के माध्यम से अप्राप्य (unreachable) प्रतीत होता है।
  • Bytecode Optimization and Access Modification: R8 मेथड्स को इनलाइन करता है, अप्रयुक्त पैरामीटर्स को हटाता है, क्लासेस को मर्ज करता है, और—जब इसे Android के डिफ़ॉल्ट ऑप्टिमाइज़ेशन कॉन्फ़िगरेशन में -allowaccessmodification डायरेक्टिव के साथ जोड़ा जाता है—तो Dalvik Executable (.dex) के आकार को कम करने और रनटाइम निष्पादन गति में सुधार करने के लिए क्लास और मेंबर विज़िबिलिटी फ़्लैग्स को संशोधित करता है (जैसे इनलाइनिंग के दौरान private या पैकेज-प्राइवेट मेंबर्स को public में बदलना)।
  • Identifier Obfuscation (Renaming and Repackaging): R8 शेष क्लासेस, पैकेजेस, फ़ील्ड्स और मेथड्स का नाम बदलकर कॉम्पैक्ट आइडेंटिफ़ायर (जैसे a.a.b()) कर देता है और classes.dex के अंदर स्ट्रिंग-पूल ओवरहेड को कम करते हुए ऑबफ़स्केटेड क्लासेस को फ़्लैट पैकेज पदानुक्रम में रीपैकेज कर सकता है।

Android Gradle Plugin (AGP) 8.0 के बाद से R8 Full Mode डिफ़ॉल्ट रूप से सक्षम है। लेगेसी ProGuard संगतता मोड की तुलना में, R8 Full Mode काफ़ी सख्त ऑप्टिमाइज़ेशन लागू करता है—डिफ़ॉल्ट नो-आर्ग्युमेंट कंस्ट्रक्टर्स (<init>()) को हटाना, मेंबर एक्सेस मोडिफ़ायर्स को बदलना, और मेटाडेटा एट्रिब्यूट्स को हटाना, जब तक कि संबंधित क्लासेस और मेंबर्स को किसी मैचिंग keep नियम द्वारा स्पष्ट रूप से बनाए न रखा गया हो। .aar बाइनरी संरचनाओं और SDK खरीद मानकों पर बुनियादी संदर्भ के लिए, हमारी सहयोगी गाइड्स मोबाइल SDK के अर्थ और तकनीकी ग्रोथ प्रोटोकॉल को समझना तथा सटीक एट्रिब्यूशन के लिए Software Development Kit कैसे चुनें देखें।

ऑबफ़स्केटेड एट्रिब्यूशन SDK में विफलता के छह अलग-अलग मोड

Android SDK रिफ्लेक्शन कॉलबैक, मॉडल्स और JNI को लक्षित R8 संरक्षण नियमों की आवश्यकता होती है।

चूंकि स्टैटिक कॉल-ग्राफ़ विश्लेषण डायनेमिक रनटाइम लुकअप का अनुमान नहीं लगा सकता है, इसलिए एक असुरक्षित Android SDK को R8 Full Mode के तहत छह अलग-अलग विफलता मोड का सामना करना पड़ सकता है। इंजीनियरों को इन विफलता मोड के बीच सावधानीपूर्वक अंतर करना चाहिए, क्योंकि प्रत्येक के लिए एक विशिष्ट ProGuard सुरक्षा लक्ष्य की आवश्यकता होती है:

रनटाइम विफलता मोड अंतर्निहित R8 बाइटकोड कारण आवश्यक विशिष्ट सुरक्षा लक्ष्य
1. रिफ्लेक्टिव क्लास लुकअप विफलता (ClassNotFoundException) R8 उस क्लास का नाम बदल देता है, रीपैकेज करता है या हटा देता है जिसे Class.forName() के माध्यम से स्ट्रिंग नाम द्वारा डायनेमिक रूप से लोड किया जाता है -keep class ... का उपयोग करके लक्ष्य क्लास और उसके मूल आइडेंटिफ़ायर को सुरक्षित रखें
2. रिफ्लेक्टिव ऑब्जेक्ट इंस्टेंटिएशन विफलता (NoSuchMethodException: <init>) R8 Full Mode में, भले ही किसी क्लास को सुरक्षित रखा गया हो, उसका डिफ़ॉल्ट नो-आर्ग्युमेंट कंस्ट्रक्टर (<init>()) हटा दिया जाता है यदि उसे कोड में सीधे कॉल नहीं किया गया है क्लास -keep ब्लॉक के अंदर कंस्ट्रक्टर सिग्नेचर (<init>();) को स्पष्ट रूप से सुरक्षित रखें
3. डायनेमिक कॉलबैक और एक्सेस मोडिफ़िकेशन विफलताएं R8 कॉलबैक इंटरफ़ेस मेथड्स को हटा देता है या उनका नाम बदल देता है, या रिफ्लेक्टिव getDeclaredMethod() / getDeclaredField() कॉल्स द्वारा अपेक्षित मेंबर विज़िबिलिटी फ़्लैग्स को बदल देता है कॉलबैक इंटरफ़ेस मेथड्स (-keep interface ... { <methods>; }) और किसी भी रिफ्लेक्टिव रूप से एक्सेस किए गए मेंबर्स को सुरक्षित रखें
4. कॉलबैक लिसनर्स में जेनेरिक सिग्नेचर मेटाडेटा की हानि Java जेनेरिक्स कंपाइल टाइम पर टाइप इरेज़र से गुज़रते हैं, जबकि बाइटकोड Signature एट्रिब्यूट्स रनटाइम रिफ्लेक्शन (ResultCallBack<OpoData>) के लिए जेनेरिक मेटाडेटा को सुरक्षित रखते हैं। R8 Full Mode स्पष्ट रूप से बनाए रखे जाने तक Signature मेटाडेटा को हटा देता है जेनेरिक कॉलबैक इंटरफ़ेस और टारगेट मॉडल क्लास दोनों को रखने के अलावा -keepattributes Signature को बनाए रखें
5. JSON डेटा मॉडल डीसीरियलाइज़ेशन विफलता R8 मॉडल क्लास को हटा देता है (यदि केवल रिफ्लेक्टिव रूप से इंस्टेंटिएट किया गया हो) या इसके फ़ील्ड्स का नाम बदलकर a, b, c कर देता है, जिससे रिफ्लेक्शन-आधारित JSON पार्सर null या खाली फ़ील्ड लौटाते हैं यदि मॉडल को डायनेमिक रूप से इंस्टेंटिएट किया गया है तो -keep class ... का उपयोग करें, या यदि क्लास पहले से ही प्रत्यक्ष रेफ़रेंस के माध्यम से सुरक्षित है तो -keepclassmembers का उपयोग करें
6. JNI डाउनकॉल और नेटिव-टू-जावा अपकॉल का हटना (UnsatisfiedLinkError / NoSuchMethodError) डिफ़ॉल्ट Android नियम बचे हुए Java native डाउनकॉल्स पर नामों को सुरक्षित रखते हैं, लेकिन अप्रयुक्त RegisterNatives मेथड्स को श्रिंक होने से नहीं रोकते हैं, और JNI (FindClass, GetMethodID) के माध्यम से Java में वापस कॉल करने वाले C/C++ .so कोड को नहीं देख सकते हैं डायनेमिक रूप से पंजीकृत native घोषणाओं और C/C++ से JNI अपकॉल्स के माध्यम से कॉल किए जाने वाले किसी भी Java क्लासेस, कंस्ट्रक्टर्स और मेथड्स को स्पष्ट रूप से -keep करें
[Android Release Build: R8 Full Mode Enabled]
                      |
                      v
     [R8 Evaluates Bundled & Host Keep Rules]
                      |
      +---------------+---------------+
      |                               |
      v (Missing / Mismatched Rules)  v (Scoped Keep Rules + Attributes Active)
[SDK Symbols Stripped or Renamed] [Required SDK Entry Points & Models Preserved]
- Reflective () Removed     - Confirmed in -printseeds (seeds.txt)
- JNI Upcall / Model Fields Lost  - Verified in Raw DEX (apkanalyzer dex packages)
- Generic Signature Metadata Lost - Release Attribution Matches Debug Behavior

AAR बंडलों में कंज़्यूमर नियम बनाम मैन्युअल JAR इम्पोर्ट

AAR और JAR लाइब्रेरी कंज़्यूमर ProGuard नियमों को कैसे बंडल करती हैं

Android AAR और JAR आर्काइव R8 कॉन्फ़िगरेशन में कंज़्यूमर नियमों का योगदान करते हैं।

अपने होस्ट एप्लिकेशन में मैन्युअल एक्सक्लूज़न नियम जोड़ने से पहले, जांच लें कि क्या थर्ड-पार्टी Android SDK पहले से ही बिल्ट-इन R8 नियमों को बंडल करता है। जैसा कि लाइब्रेरी ऑप्टिमाइज़ेशन पर Google Android Developers गाइड में प्रलेखित है, AGP और R8 वर्शन-लक्षित R8 नियमों सहित .aar और .jar दोनों वितरणों में स्वचालित कंज़्यूमर नियम डिस्कवरी का समर्थन करते हैं:

SDK वितरण फ़ॉर्मेट एम्बेडेड कंज़्यूमर नियम का स्थान Android Gradle Plugin / R8 बिल्ड व्यवहार
Android Archive (.aar) AAR रूट पर /proguard.txt (consumerProguardFiles के माध्यम से), या /META-INF/com.android.tools/r8-from-<X>-upto-<Y>/ के तहत /classes.jar के अंदर वर्शन-लक्षित नियम कंपाइल टाइम पर स्वचालित रूप से निकाला जाता है और होस्ट App के R8 कॉन्फ़िगरेशन में मर्ज किया जाता है
बंडल किए गए नियमों के साथ Java Archive (.jar) /META-INF/proguard/*.pro या /META-INF/com.android.tools/r8-from-<X>-upto-<Y>/ (r8, r8-from-<X>, और r8-upto-<Y> वेरिएंट सहित) सक्रिय R8 कंपाइलर वर्शन के अनुसार AGP और R8 द्वारा स्वचालित रूप से खोजा और लागू किया जाता है
बंडल किए गए नियमों के बिना स्टैंडअलोन .jar या .aar आर्काइव के अंदर कुछ भी मौजूद नहीं है कोई बंडल कंज़्यूमर सुरक्षा प्रदान नहीं की जाती है; होस्ट-स्तरीय keep नियम केवल तभी जोड़ें जब रनटाइम रिफ्लेक्शन, JNI, सीरियलाइज़ेशन या अन्य डायनेमिक रूप से एक्सेस किए गए सिंबल्स को स्पष्ट संरक्षण की आवश्यकता हो

(Gson सीरियलाइज़ेशन नियमों पर नोट: जैसा कि ProGuard और R8 के लिए Gson समस्या निवारण गाइड में प्रलेखित है, Gson 2.11.0 और बाद के वर्शन TypeToken और @SerializedName के साथ एनोटेट किए गए फ़ील्ड्स के लिए R8 नियमों को बंडल करते हैं। ये नियम रिफ्लेक्टिव मॉडल एक्सेस को सीमित करने, संगत नो-आर्ग्युमेंट कंस्ट्रक्टर्स प्रदान करने, या मिनिफ़ाइड रिलीज़ बिल्ड में सभी सीरियलाइज़ेशन और डीसीरियलाइज़ेशन पथों का परीक्षण करने की आवश्यकता को समाप्त नहीं करते हैं।)

नियम लिखने से पहले अपने डाउनलोड किए गए SDK आर्काइव का निरीक्षण करना

ProGuard और R8 नियम मिलान सख्ती से केस-सेंसिटिव (case-sensitive) और पैकेज-पाथ के प्रति सटीक होता है। विभिन्न SDK वर्शन या क्षेत्रीय वितरणों में, पैकेज नेमस्पेस भिन्न हो सकते हैं—और यदि आप किसी पुराने ट्यूटोरियल से कोई नियम कॉपी करते हैं जिसका पैकेज कैपिटलाइज़ेशन आपके आर्काइव में वास्तविक .class फ़ाइलों से मेल नहीं खाता है, तो R8 चुपचाप शून्य क्लासेस से मेल खाएगा।

अपने keep नियमों को संपादित करने से पहले, अपना टारगेट SDK पैकेज डाउनलोड करें (जैसे कि मोबाइल SDK डाउनलोड सेंटर से Android SDK v2.1.0) और इसके सटीक .class पदानुक्रम के साथ इसके एम्बेडेड नियमों (/proguard.txt और classes.jar दोनों के अंदर) का निरीक्षण करें:

# 1. Inspect an .aar archive for root consumer rules (proguard.txt) and extract classes.jar to check META-INF rules
unzip -l opoinstall-android-sdk.aar
unzip -p opoinstall-android-sdk.aar proguard.txt
unzip -p opoinstall-android-sdk.aar classes.jar > temp_classes.jar
jar tf temp_classes.jar | grep -E "META-INF/proguard/|META-INF/com\.android\.tools/|\.class$"

# 2. If using a standalone .jar archive, inspect embedded META-INF rules and exact case-sensitive .class paths
jar tf libs/OpoInstall_SDK.jar | grep -E "META-INF/proguard/|META-INF/com\.android\.tools/|\.class$"

एट्रिब्यूशन Android SDK के लिए proguard-rules.pro को कॉन्फ़िगर करना

पैकेज-वाइड Keep एंटी-पैटर्न और व्यापक चेतावनी दमन (Blanket Warning Suppressions) से बचना

कस्टम नियम लिखते समय, इंजीनियरों को अनावश्यक रूप से ऑप्टिमाइज़ेशन को अक्षम करने से बचने के लिए Google के Choose What to Keep (R8 Keep Rules) की सर्वोत्तम कार्यप्रणालियों का पालन करना चाहिए:

  • पैकेज-वाइड -keep class package.** { *; } एंटी-पैटर्न की तुलना में संकीर्ण (Narrow) नियमों को प्राथमिकता दें: एक व्यापक पैकेज-वाइड नियम R8 को उस पैकेज में प्रत्येक आंतरिक हेल्पर क्लास को बनाए रखने और उस पर ऑप्टिमाइज़ेशन छोड़ने के लिए मजबूर करता है। अपने नियमों को उन विशिष्ट क्लासेस, कंस्ट्रक्टर्स (<init>();), कॉलबैक इंटरफ़ेस, JNI टारगेट्स और मॉडल फ़ील्ड्स तक सीमित रखें जिन्हें रनटाइम पर डायनेमिक रूप से एक्सेस किया जाता है (या जिस कोड को आप नियंत्रित करते हैं उस पर Jetpack के @UnconditionallyKeep एनोटेशन का उपयोग करें)।
  • डेटा मॉडल्स पर -keep को -keepclassmembers से अलग करें: -keepclassmembers निर्दिष्ट फ़ील्ड्स या मेथड्स को तभी सुरक्षित रखता है जब संबंधित क्लास को कॉल ग्राफ़ में बनाए रखा जाता है। यदि कोई डेटा मॉडल (जैसे OpoData) केवल रिफ्लेक्शन के माध्यम से इंस्टेंटिएट किया जाता है या केवल मिटाए गए (erased) जेनेरिक प्रकारों के माध्यम से संदर्भित किया जाता है, तो -keep class ... का उपयोग करें ताकि R8 स्वयं उस क्लास को न हटाए।
  • JNI के लिए -keepclasseswithmembernames की सीमाओं को समझें: Android के डिफ़ॉल्ट ऑप्टिमाइज़ेशन नियमों में -keepclasseswithmembernames,includedescriptorclasses class * { native <methods>; } शामिल है। जैसा कि Google के R8 Keep Rules दस्तावेज़ीकरण और Keep Directives पर ProGuard मैनुअल में परिभाषित किया गया है, -keepclasseswithmembernames -keepclasseswithmembers,allowshrinking के समतुल्य है। यह उन मैचिंग क्लासेस और मेंबर्स के नामों को सुरक्षित रखता है जो श्रिंकिंग चरण में बचे रहते हैं, लेकिन यह श्रिंकिंग के दौरान बिना रेफ़रेंस वाले क्लासेस या native मेथड्स को हटाए जाने से नहीं रोकता है। यदि नेटिव मेथड्स को प्रत्यक्ष Java कॉल साइट्स के बिना RegisterNatives के माध्यम से डायनेमिक रूप से पंजीकृत किया जाता है, या यदि C/C++ कोड JNI अपकॉल्स के माध्यम से Java मेथड्स को कॉल करता है, तो आपको टारगेट क्लास को इंस्टेंटिएट किए जाने के तरीके के अनुसार स्पष्ट -keep या -keepclassmembers नियमों का उपयोग करना चाहिए।
  • असत्यापित व्यापक -dontwarn डायरेक्टिव से बचें: -dontwarn श्रिंकिंग या रीनेमिंग के विरुद्ध शून्य सुरक्षा प्रदान करता है और अनसुलझे रेफ़रेंस चेतावनियों को दबा देता है जो रनटाइम NoClassDefFoundError क्रैश को छिपा सकते हैं। एक संकीर्ण रूप से स्कोप किया गया -dontwarn केवल तभी जोड़ें जब आपका बिल्ड लॉग एक विशिष्ट अनुपलब्ध कंपाइल-ओनली क्लास की रिपोर्ट करता है जिसे आपने सत्यापित किया है कि वह रनटाइम पर वैकल्पिक है।
ProGuard / R8 डायरेक्टिव समतुल्य लॉन्ग-फ़ॉर्म सिंटैक्स श्रिंकिंग (हटाना) ऑबफ़स्केशन (नाम बदलना) अनुशंसित इंजीनियरिंग स्कोप
-keep class ... -keep रोका गया (क्लास और निर्दिष्ट मेंबर्स रखे गए) रोका गया (मूल नाम रखे गए) पब्लिक SDK एंट्री पॉइंट्स, कॉलबैक इंटरफ़ेस, और रिफ्लेक्शन या JNI के माध्यम से डायनेमिक रूप से इंस्टेंटिएट किए गए क्लासेस (<init>(...); शामिल करें)
-keepclassmembers class ... -keepclassmembers मेंबर्स केवल तभी रखे जाते हैं जब क्लास को बनाए रखा जाए मैच किए गए मेंबर्स के लिए रोका गया उन क्लासेस पर <fields>; या JNI अपकॉल मेथड्स को सुरक्षित रखना जो पहले से ही सीधे Java/Kotlin में इंस्टेंटिएट किए गए हैं
-keepclasseswithmembernames -keepclasseswithmembers,allowshrinking यदि कोई रेफ़रेंस न हो तो अनुमति है (allowshrinking) यदि क्लास और मेंबर्स श्रिंकिंग में बच जाते हैं तो रोका जाता है डिफ़ॉल्ट JNI डाउनकॉल नाम संरक्षण (native <methods>;) जब Java कोड सीधे native मेथड को कॉल करता है
-keepnames class ... -keep,allowshrinking यदि कोई रेफ़रेंस न हो तो अनुमति है (allowshrinking) यदि क्लास को बनाए रखा जाता है तो रोका जाता है अप्रयुक्त क्लासेस को classes.dex में ज़बरदस्ती डाले बिना स्टैक ट्रेस के लिए पठनीय क्लास नाम रखना
-keepattributes ... -keepattributes रखे गए आइटम्स पर मेटाडेटा सुरक्षित रखता है लागू नहीं (बाइटकोड एट्रिब्यूट) स्पष्ट रूप से रखे गए क्लासेस पर Signature (जेनेरिक्स), InnerClasses, EnclosingMethod, और *Annotation* को बनाए रखना
-dontwarn <specific_class> -dontwarn श्रिंकिंग पर कोई प्रभाव नहीं नाम बदलने पर कोई प्रभाव नहीं केवल एक सत्यापित, वैकल्पिक कंपाइल-ओनली डिपेंडेंसी के लिए कंपाइल-टाइम चेतावनियों को दबाना

AGP 8.x और AGP 9.3+ टूलचेन में Gradle को कॉन्फ़िगर करना

Android Gradle Plugin 9.3 ने एक सरलीकृत optimization DSL ब्लॉक और वेरिएंट-विशिष्ट keepRules डायरेक्टरी (.keep फ़ाइलें) पेश कीं, जबकि AGP 8.x से 9.2 (और AGP 9.3+ में अभी भी समर्थित लेगेसी कॉन्फ़िगरेशन) isMinifyEnabled और proguardFiles का उपयोग करते हैं। इंजीनियरों को तीन कॉन्फ़िगरेशन ऑब्जेक्ट्स को अलग रखना चाहिए:

कॉन्फ़िगरेशन ऑब्जेक्ट फ़ाइल या DSL स्थान R8 बिल्ड में आर्किटेक्चरल भूमिका
लेगेसी DSL Keep Rules (AGP 8.x–9.2 और लेगेसी 9.3+) app/proguard-rules.pro (proguardFiles(...) के माध्यम से संदर्भित) getDefaultProguardFile("proguard-android-optimize.txt") के साथ होस्ट keep नियमों को घोषित करता है
नए ऑप्टिमाइज़ेशन DSL Keep Rules (AGP 9.3+) app/src/main/keepRules/*.keep या app/src/<variant>/keepRules/*.keep optimization { enable = true } का उपयोग करते समय .keep फ़ाइलों को घोषित करता है (डिफ़ॉल्ट Android प्लेटफ़ॉर्म नियम स्वचालित रूप से लागू होते हैं; लेगेसी DSL भी .keep सोर्स सेट का समर्थन करता है)
R8 डायग्नोस्टिक रिपोर्ट डायरेक्टिव एक सत्यापित R8 कॉन्फ़िगरेशन फ़ाइल (proguard-rules.pro) में -printseeds, -printusage, -printconfiguration R8 को app/build/outputs/mapping/<buildVariant>/ में ऑडिट रिपोर्ट जारी करने का निर्देश देता है
// Option A: AGP 8.x - 9.2 Legacy DSL (also supported in AGP 9.3+) — app/build.gradle.kts
android {
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

// Option B: AGP 9.3+ Simplified Optimization DSL — app/build.gradle.kts
// Place scoped class/member keep rules in app/src/main/keepRules/sdk-attribution.keep
android {
    buildTypes {
        release {
            optimization {
                enable = true
            }
        }
    }
}

उदाहरणार्थ स्कोप किए गए Keep नियम और डायग्नोस्टिक डायरेक्टिव

चूंकि OpoInstall के सार्वजनिक दस्तावेज़ीकरण और ऐतिहासिक FAQ पृष्ठ विभिन्न पैकेज प्रीफ़िक्स (com.opoinstall.api.** बनाम com.fm.OpoInstall.** या io.OpoInstall.**) का संदर्भ देते हैं, इसलिए नीचे दिया गया नियम सेट केवल उदाहरण के लिए है—यह OpoInstall SDK v2.1.0 के लिए सत्यापित प्रोडक्शन नियम सेट नहीं है। पहले अपने डाउनलोड किए गए v2.1.0 आर्काइव के अंदर वास्तविक क्लास पाथ और बंडल किए गए कंज़्यूमर नियमों का निरीक्षण करें, और OpoInstall तकनीकी दस्तावेज़ीकरण से परामर्श लें (अंतर्निहित Java लाइफ़साइकिल कोड के लिए Software Development Kits मोबाइल एट्रिब्यूशन और ग्रोथ को कैसे सशक्त बनाते हैं देखें):

# File: app/src/main/keepRules/sdk-attribution.keep (or app/proguard-rules.pro)
# IMPORTANT: Illustrative only — not a verified production rule set for OpoInstall SDK v2.1.0.
# Verify exact case-sensitive package and class names inside your downloaded v2.1.0 archive
# via `jar tf` or `apkanalyzer`, and check `configuration.txt` for existing consumer rules.

# ---------------------------------------------------------------------------
# 1. Preserve Bytecode Attributes on Explicitly Kept Classes
# Required so generic callback interfaces (e.g., ResultCallBack<OpoData>)
# retain their parameterized type metadata in R8 Full Mode.
# ---------------------------------------------------------------------------
-keepattributes Signature, InnerClasses, EnclosingMethod, *Annotation*

# ---------------------------------------------------------------------------
# 2. Scoped SDK Entry Point, Callback Interface, and Data Model Rules
# ---------------------------------------------------------------------------

# Preserve public SDK entry point and any reflectively invoked constructors/methods:
-keep public class com.opoinstall.api.OpoInstall {
    <init>(...);
    public <methods>;
}

# Preserve callback listener interfaces and their callback methods:
-keep public interface com.opoinstall.api.ResultCallBack {
    public <methods>;
}

# Model Scenario A: If OpoData / OpoError models are instantiated dynamically via reflection
# or referenced only via erased generics, use -keep to preserve both the class and its members:
-keep class com.opoinstall.api.OpoData {
    <init>(...);
    <fields>;
    public <methods>;
}
-keep class com.opoinstall.api.OpoError {
    <init>(...);
    <fields>;
    public <methods>;
}

# Model Scenario B: If a model class is already directly retained in your host call graph
# and only its fields require protection from renaming, use -keepclassmembers:
# -keepclassmembers class com.opoinstall.api.OpoData { <fields>; }

# ---------------------------------------------------------------------------
# 3. JNI Downcall and Native-to-Java Upcall Protection (Illustrative JNI Patterns)
# ---------------------------------------------------------------------------
# JNI Case A: If Java/Kotlin code already directly instantiates the JNI bridge class,
# use -keepclassmembers,includedescriptorclasses for C/C++ upcall methods, and keep
# any parameter model classes/constructors instantiated by native code:
-keepclassmembers,includedescriptorclasses class com.example.sdk.internal.JniBridge {
    public void onNativeAttributionEvent(com.example.sdk.internal.NativeEventData);
}
-keep class com.example.sdk.internal.NativeEventData {
    <init>(...);
}

# JNI Case B: If native C/C++ code dynamically looks up or instantiates the Java class
# itself via FindClass / NewObject, or registers native methods via RegisterNatives
# without direct Java call sites, use -keep to prevent class and method removal:
-keep,includedescriptorclasses class com.example.sdk.internal.DynamicNativeBridge {
    <init>(...);
    public native <methods>;
    public void onNativeCallback(java.lang.String);
}
# File: app/proguard-rules.pro (Diagnostic Output Directives)
# Place R8 diagnostic report flags in your verified R8 configuration file.
# Paths resolve relative to the module working directory (`app/`).
# Adjust the directory name for product flavors (e.g., build/outputs/mapping/prodRelease/).
-printseeds build/outputs/mapping/release/seeds.txt
-printusage build/outputs/mapping/release/usage.txt
-printconfiguration build/outputs/mapping/release/configuration.txt

Android चैनल पैकेज ऑबफ़स्केशन और हार्डनिंग विरोधों को हल करना

बिल्ड-टाइम R8 कंपाइलेशन, APK अलाइनमेंट, साइनिंग और चैनल पैकेज को अलग करना

Google Play के बाहर Android वितरणों के लिए, OpoInstall समर्पित Android चैनल पैकेज एक्सपोर्ट करने का समर्थन करता है—डेवलपर द्वारा अपलोड किए गए बेस APK को लेकर और अलग channelCode ट्रैकिंग मेटाडेटा वाले चैनल-विशिष्ट APK जनरेट करके।

एक्सपोर्ट किए गए चैनल पैकेजों पर गायब चैनल आंकड़ों या इंस्टॉलेशन विफलताओं का समस्या निवारण करते समय, इंजीनियरों को दो स्वतंत्र रिलीज़ सत्यापन मानदंडों को अलग करना चाहिए—क्रिप्टोग्राफ़िक APK सिग्नेचर वैधता और वेंडर चैनल मेटाडेटा अखंडता:

  1. बिल्ड-टाइम R8 कोड श्रिंकिंग: बेस APK के पैकेज और साइन किए जाने से पहले जब Java/Kotlin बाइटकोड को classes.dex में कंपाइल किया जाता है, तब R8 Gradle बिल्ड पाइपलाइन के अंदर निष्पादित होता है। R8 को कभी भी पहले से एक्सपोर्ट किए गए APK पर नहीं चलाया जाता है।
  2. Android APK अलाइनमेंट (zipalign) और क्रिप्टोग्राफ़िक साइनिंग (apksigner): AGP द्वारा बनाए गए मानक रिलीज़ APK स्वचालित रूप से अलाइन हो जाते हैं। हालांकि, यदि आपकी रिलीज़ पाइपलाइन साइन करने से पहले कस्टम पोस्ट-प्रोसेसिंग या थर्ड-पार्टी APK रीइन्फोर्समेंट (reinforcement) लागू करती है, तो आपको आधिकारिक Android zipalign विनिर्देशों और Android apksigner विनिर्देशों के तहत APK को फिर से अलाइन करना होगा। zipalign अनकंप्रेस्ड डेटा को 4-बाइट सीमाओं पर अलाइन करता है—और यदि APK में अनकंप्रेस्ड नेटिव .so लाइब्रेरी शामिल हैं, तो टीमों को 16 KB पेज अलाइनमेंट आवश्यकताओं को पूरा करने के लिए zipalign -P 16 -f -v 4 infile.apk outfile.apk का उपयोग करना चाहिए और zipalign -c -P 16 -v 4 के साथ अलाइनमेंट को सत्यापित करना चाहिए। apksigner के साथ साइन करने से पहले zipalign को निष्पादित किया जाना आवश्यक है, क्योंकि साइन करने के बाद APK को संशोधित करने से इसका V2/V3 होल-APK क्रिप्टोग्राफ़िक सिग्नेचर अमान्य हो जाता है।
  3. वेंडर-विशिष्ट चैनल मेटाडेटा और सिग्नेचर सत्यापन: OpoInstall कंसोल से चैनल APK एक्सपोर्ट करने के बाद थर्ड-पार्टी APK रीइन्फोर्समेंट (पैकिंग) या री-पैकेजिंग टूल्स चलाने से एम्बेडेड चैनल मेटाडेटा ओवरराइट हो सकता है या APK सिग्नेचर अमान्य हो सकता है। यदि किसी थर्ड-पार्टी चैनल-पैकेज पार्सर को एक विशिष्ट APK सिग्नेचर स्कीम (जैसे V2/V3 होल-APK साइनिंग के साथ V1 JAR साइनिंग सक्षम करना) की आवश्यकता होती है, तो प्रोडक्शन साइनिंग कॉन्फ़िग को संशोधित करने से पहले उस आवश्यकता को सीधे अपने वर्तमान OpoInstall कंसोल दस्तावेज़ीकरण या वेंडर सपोर्ट से सत्यापित करें, और V1 साइनिंग को एक सार्वभौमिक Android OS आवश्यकता के रूप में न मानें।

Android चैनल पैकेजों के लिए अनुशंसित रिलीज़ पाइपलाइन क्रम

वैध APK सिग्नेचर, R8 बाइटकोड ऑप्टिमाइज़ेशन और अक्षुण्ण वेंडर चैनल मेटाडेटा बनाए रखने के लिए, अपनी रिलीज़ पाइपलाइन को इस सख्त अनुक्रम में निष्पादित करें:

  1. R8 के साथ बेस APK को कंपाइल और मिनिफ़ाई करें: अपने सत्यापित keep नियमों के साथ ./gradlew :app:assembleRelease चलाएं ताकि R8 बिल्ड टाइम पर classes.dex को ऑप्टिमाइज़ कर सके।
  2. अपलोड से पहले की किसी भी हार्डनिंग, अलाइनमेंट और साइनिंग को पूरा करें: यदि आपकी सुरक्षा टीम थर्ड-पार्टी APK रीइन्फोर्समेंट टूल्स का उपयोग करती है, तो उन्हें बेस APK पर लागू करें, zipalign -P 16 -f -v 4 चलाएं (यदि साइन करने से पहले री-अलाइनमेंट की आवश्यकता है), zipalign -c -P 16 -v 4 के साथ अलाइनमेंट को सत्यापित करें, और बेस APK को साइन करें।
  3. बेस APK अपलोड करें और एक्सपोर्ट किए गए चैनल APK को स्वतंत्र रूप से सत्यापित करें: साइन किए गए, ऑबफ़स्केटेड बेस APK को OpoInstall कंसोल पर अपलोड करें, चैनल APK एक्सपोर्ट करें, और सार्वजनिक वितरण से पहले एक्सपोर्ट किए गए APK पर क्रिप्टोग्राफ़िक सिग्नेचर वैधता (apksigner verify --verbose) और फ़िज़िकल-डिवाइस चैनल एट्रिब्यूशन दोनों को स्वतंत्र रूप से सत्यापित करें।
[Recommended Channel Package Pipeline]:
Source Code -> Gradle R8 Minification -> (Optional Pre-Upload Hardening + zipalign -P 16 + Signing) -> Upload Base APK to Console -> Export Channel APK -> Verify Both Signature (apksigner) & Channel Callback

R8 रिपोर्ट और APK Analyzer का उपयोग करके सुरक्षित किए गए SDK सिंबल्स का ऑडिट करना

AGP 9.3+ में स्टैंडअलोन R8 कॉन्फ़िगरेशन एनालाइज़र का उपयोग करना

Android Gradle Plugin 9.3 और बाद के वर्शन में, आपको यह ऑडिट करने के लिए कि आपके keep नियम कैसे मर्ज और मैच होते हैं, पूर्ण रिलीज़ APK या App Bundle कंपाइलेशन की प्रतीक्षा करने की आवश्यकता नहीं है। AGP 9.3+ एक समर्पित analyze<Variant>R8Config Gradle टास्क (उदाहरण के लिए, ./gradlew :app:analyzeReleaseR8Config) प्रदान करता है, जो कंज़्यूमर और होस्ट keep नियमों का तेज़ी से मूल्यांकन करता है और कॉन्फ़िगरेशन डायग्नोस्टिक्स आउटपुट करता है ताकि इंजीनियर पूर्ण रिलीज़ बिल्ड चलाने से पहले .keep नियमों को दोहरा सकें और सुधार सकें।

configuration.txt, seeds.txt, usage.txt, और mapping.txt की क्रॉस-चेकिंग

Android R8 रिपोर्ट और रॉ DEX निरीक्षण चैनल APK रिलीज़ अखंडता को सत्यापित करते हैं।

कभी भी यह न मान लें कि एक -keep नियम ने केवल इसलिए काम किया क्योंकि ./gradlew :app:assembleRelease बिना किसी बिल्ड त्रुटि के समाप्त हो गया। अपने कॉन्फ़िगरेशन को निश्चित रूप से सत्यापित करने के लिए, app/build/outputs/mapping/<buildVariant>/ में जनरेट की गई चार R8 डायग्नोस्टिक फ़ाइलों का निरीक्षण करें (यह डीबग करते समय कि किसी विशिष्ट सिंबल को क्यों बनाए रखा गया था, -whyareyoukeeping class <ClassName> का उपयोग करें):

  • configuration.txt: इसमें R8 द्वारा लागू किया गया पूर्ण, मर्ज किया गया नियम सेट शामिल होता है—जो आपके होस्ट keep नियमों, डिफ़ॉल्ट Android प्लेटफ़ॉर्म नियमों, AAPT2 नियमों, और लिंक की गई .aar और .jar लाइब्रेरी के अंदर बंडल किए गए किसी भी /proguard.txt या /META-INF/ नियमों को जोड़ता है।
  • seeds.txt: आपके सक्रिय -keep नियमों से मेल खाने वाले प्रत्येक क्लास, कंस्ट्रक्टर (<init>()), मेथड और फ़ील्ड को सूचीबद्ध करता है। ध्यान दें कि seeds.txt में मिलान नियम सिंटैक्स की पुष्टि करता है, लेकिन इसे DEX निरीक्षण और रनटाइम परीक्षण के साथ जोड़ा जाना चाहिए।
  • usage.txt: उस डेड कोड को सूचीबद्ध करता है जिसे R8 ने ट्री-शेकिंग के दौरान APK से हटा दिया है। पुष्टि करें कि आपके आवश्यक SDK क्लासेस, रिफ्लेक्टिव कंस्ट्रक्टर्स, या JNI अपकॉल मेथड्स में से कोई भी usage.txt में दिखाई नहीं देता है।
  • mapping.txt: बनाए रखे गए क्लासेस और मेंबर्स के लिए पहले और बाद के आइडेंटिफ़ायर अनुवाद मैप को रिकॉर्ड करता है। ध्यान दें कि mapping.txt से अनुपस्थिति यह साबित नहीं करती है कि किसी क्लास को उसके मूल नाम के तहत सुरक्षित रखा गया था—हो सकता है कि उसे श्रिंकिंग के दौरान पूरी तरह से हटा दिया गया हो (और usage.txt में सूचीबद्ध किया गया हो)। हमेशा mapping.txt को seeds.txt, usage.txt और कंपाइल की गई DEX फ़ाइल के साथ क्रॉस-रेफ़रेंस करें।

apkanalyzer के साथ रॉ DEX आइडेंटिफ़ायर बनाम डी-ऑबफ़स्केटेड रिपोर्ट स्थितियों को सत्यापित करना

अपने रिलीज़ APK का निरीक्षण करने के लिए आधिकारिक Google Android Developers APK Analyzer CLI का उपयोग करते समय, रॉ कंपाइल किए गए DEX आइडेंटिफ़ायर और मैपिंग-डीऑबफ़स्केटेड नामों के बीच अंतर करें:

  • रॉ कंपाइल किए गए DEX नामों का निरीक्षण करना (--proguard-mappings के बिना): जब आप apkanalyzer को --proguard-mappings mapping.txt पास करते हैं, तो टूल प्रदर्शन के लिए ऑबफ़स्केटेड DEX नामों (जैसे a.b.c) को वापस उनके मूल सोर्स नामों में अनुवादित करता है। इसलिए, जब --proguard-mappings सक्षम होता है तो मूल क्लास नाम देखने से यह साबित नहीं होता है कि सिंबल classes.dex में नाम बदलने से बच गया है। पहले --proguard-mappings के बिना apkanalyzer dex packages चलाएं। चूंकि R8 क्लास रीपैकेजिंग क्लासेस को फ़्लैट पैकेज पाथ में भी ले जा सकता है, इसलिए केवल पैकेज grep पर भरोसा न करें; रॉ DEX क्लास ट्री का निरीक्षण करें, रिफ्लेक्शन एंट्री-पॉइंट क्लास नामों को सत्यापित करें, JNI मेथड नामों और डिस्क्रिप्टर सिग्नेचर की जांच करें, और यह पुष्टि करने के लिए mapping.txt को क्रॉस-चेक करें कि आवश्यक मेथड्स और फ़ील्ड्स का नाम नहीं बदला गया था।
  • R8 प्रतिधारण स्थितियों (Retention States) का निरीक्षण करना (--proguard-mappings, --proguard-seeds, और --proguard-usages के साथ): दूसरे चरण में, प्रत्येक पैकेज (P), क्लास (C), मेथड (M), और फ़ील्ड (F) में प्रतिधारण फ़्लैग्स (सीड नियम द्वारा रखे गए के लिए k, श्रिंकिंग के दौरान हटाए गए के लिए x, संदर्भित के लिए r, और परिभाषित के लिए d) को फिर से बनाने के लिए सभी तीन R8 रिपोर्ट फ़ाइलें प्रदान करें:
# Run from the Android project root directory (adjust variant path for product flavors, e.g., prodRelease)

# 1. (AGP 9.3+) Run the standalone R8 configuration analyzer for rapid rule verification, then build release APK
./gradlew :app:analyzeReleaseR8Config
./gradlew :app:assembleRelease

# 2. Inspect the merged R8 configuration, matched seeds, and stripped usage reports
grep -i -C 3 "opoinstall" app/build/outputs/mapping/release/configuration.txt
grep -i "opoinstall" app/build/outputs/mapping/release/seeds.txt
grep -i "opoinstall" app/build/outputs/mapping/release/usage.txt

# 3A. Inspect RAW compiled DEX identifiers (WITHOUT --proguard-mappings)
# Also inspect the full raw DEX tree and cross-check mapping.txt in case R8 repackaged classes
apkanalyzer dex packages app/build/outputs/apk/release/app-release.apk | grep -i "opoinstall"

# 3B. Inspect R8 retention state flags (k = kept, x = removed, r = referenced, d = defined) WITH R8 report files
apkanalyzer dex packages \
  --proguard-mappings app/build/outputs/mapping/release/mapping.txt \
  --proguard-seeds app/build/outputs/mapping/release/seeds.txt \
  --proguard-usages app/build/outputs/mapping/release/usage.txt \
  app/build/outputs/apk/release/app-release.apk | grep -i "opoinstall"

# 4. Verify 16 KB page alignment (if native .so files are present) and cryptographic APK signatures
zipalign -c -P 16 -v 4 app/build/outputs/apk/release/app-release.apk
apksigner verify --verbose app/build/outputs/apk/release/app-release.apk

रिलीज़ बिल्ड एट्रिब्यूशन समस्या निवारण मैट्रिक्स

मिनिफ़ाइड Android बिल्ड में साइलेंट एट्रिब्यूशन और Deep-Link विफलताओं का निदान करना

केवल मिनिफ़ाइड रिलीज़ बिल्ड में होने वाली एट्रिब्यूशन विसंगतियों का समस्या निवारण करते समय, मूल कारण को अलग करने के लिए नीचे दिए गए डायग्नोस्टिक मैट्रिक्स का उपयोग करें:

देखा गया रिलीज़ लक्षण संभावित R8 / बिल्ड मूल कारण डायग्नोस्टिक सत्यापन चरण सुधारात्मक कार्रवाई
रिलीज़ बिल्ड में getInstallParam या handleDeepLink कॉलबैक कभी फ़ायर नहीं होता है पैकेज बेमेल होने के कारण SDK एंट्री-पॉइंट क्लासेस, रिफ्लेक्टिव <init>() कंस्ट्रक्टर्स, या ResultCallBack मेथड्स हटा दिए गए थे या उनका नाम बदल दिया गया था seeds.txt और usage.txt की जांच करें; रॉ apkanalyzer dex packages आउटपुट (--proguard-mappings के बिना) और mapping.txt का निरीक्षण करें सटीक केस-सेंसिटिव क्लास पाथ खोजने के लिए jar tf के साथ .jar / .aar का निरीक्षण करें और <init>(...); सहित स्कोप किए गए -keep नियम जोड़ें
कॉलबैक फ़ायर होता है, लेकिन OpoData कस्टम पैरामीटर्स खाली या null के रूप में पार्स होते हैं OpoData को केवल -keepclassmembers के साथ सुरक्षित किया गया था (जिससे क्लास को स्वयं हटाए जाने की अनुमति मिली) या जेनेरिक Signature मेटाडेटा खो गया था OpoData के लिए usage.txt और mapping.txt की जांच करें और -keepattributes Signature के लिए configuration.txt की जांच करें <init>(...); <fields>; के साथ -keep class ... का उपयोग करें (यदि OpoData रिफ्लेक्टिव रूप से इंस्टेंटिएट किया गया है) और -keepattributes Signature को बनाए रखें
जब SDK .so लाइब्रेरी लोड करता है तो UnsatisfiedLinkError या गायब नेटिव कॉलबैक डायनेमिक रूप से पंजीकृत RegisterNatives डाउनकॉल्स श्रिंक हो गए थे या C/C++ से Java अपकॉल टारगेट मेथड्स का नाम R8 द्वारा बदल दिया गया था सटीक गायब JNI सिंबल के लिए logcat का निरीक्षण करें और टारगेट Java क्लास के लिए रॉ apkanalyzer dex packages और mapping.txt की जांच करें JNI अपकॉल और RegisterNatives टारगेट्स पर includedescriptorclasses के साथ -keep (या यदि ब्रिज क्लास सीधे Java में इंस्टेंटिएट किया गया है तो -keepclassmembers) का उपयोग करें
एक्सपोर्ट किया गया Android चैनल पैकेज इंस्टॉलेशन में विफल रहता है या चैनल आंकड़े छोड़ देता है एक्सपोर्ट के बाद के APK संशोधन ने APK सिग्नेचर को अमान्य कर दिया या एम्बेडेड चैनल मेटाडेटा को ओवरराइट कर दिया एक्सपोर्ट किए गए चैनल APK पर zipalign -c -P 16 -v 4 और apksigner verify --verbose चलाएं और फ़िज़िकल डिवाइस पर परीक्षण करें कंसोल पर अपलोड करने से पहले बेस APK पर सभी R8 मिनिफ़िकेशन, हार्डनिंग, अलाइनमेंट और साइनिंग पूरी करें; एक्सपोर्ट के बाद सिग्नेचर और एट्रिब्यूशन दोनों को सत्यापित करें

अक्सर पूछे जाने वाले प्रश्न (FAQ)

मैं किसी मोबाइल SDK को Android ProGuard और R8 ऑबफ़स्केशन से कैसे बाहर रखूं?
सबसे पहले, अपने `.aar` (`/proguard.txt` और `classes.jar/META-INF/com.android.tools/`) या `.jar` (`/META-INF/proguard/` और `/META-INF/com.android.tools/`) आर्काइव का निरीक्षण करें और यह देखने के लिए `configuration.txt` की जांच करें कि क्या कंज़्यूमर ProGuard नियम पहले से ही बंडल किए गए हैं। यदि मैन्युअल नियमों की आवश्यकता है, तो `-keepattributes Signature, InnerClasses, EnclosingMethod, *Annotation*` के साथ जोड़कर सटीक केस-सेंसिटिव SDK एंट्री क्लासेस, रिफ्लेक्टिव कंस्ट्रक्टर्स (`<init>(...);`), कॉलबैक इंटरफ़ेस, JNI टारगेट्स, और मॉडल `<fields>;` को लक्षित करते हुए संकीर्ण रूप से स्कोप किए गए `-keep` और `-keepclassmembers` डायरेक्टिव जोड़ें।
मैं यह कैसे सत्यापित करूं कि मेरे Android SDK क्लासेस को R8 ऑबफ़स्केशन से बाहर रखा गया था?
अपने R8 कॉन्फ़िगरेशन में `-printseeds`, `-printusage`, और `-printconfiguration` को सक्षम करें (या AGP 9.3+ में `./gradlew :app:analyzeReleaseR8Config` चलाएं) और अपना रिलीज़ APK बनाएं। सत्यापित करें कि आपके टारगेट SDK क्लासेस और कंस्ट्रक्टर्स `seeds.txt` में दिखाई देते हैं और `usage.txt` में दिखाई नहीं देते हैं। इसके बाद, `--proguard-mappings` **के बिना** `apkanalyzer dex packages app-release.apk` चलाएं और यह पुष्टि करने के लिए `mapping.txt` को क्रॉस-चेक करें कि रॉ कंपाइल किए गए DEX सिंबल्स अपने मूल अन-ऑबफ़स्केटेड नाम और मेथड सिग्नेचर बनाए रखते हैं, फिर प्रतिधारण स्थिति फ़्लैग्स (`k`, `x`, `r`, `d`) का ऑडिट करने के लिए `--proguard-mappings`, `--proguard-seeds`, और `--proguard-usages` के साथ दूसरी बार `apkanalyzer` चलाएं।
APK हार्डनिंग या पोस्ट-प्रोसेसिंग के बाद Android चैनल पैकेज के आंकड़े काम करना क्यों बंद कर देते हैं?
जब आप एट्रिब्यूशन कंसोल से एक Android चैनल पैकेज एक्सपोर्ट करते हैं, तो चैनल पहचान मेटाडेटा को एक्सपोर्ट किए गए APK में एम्बेड कर दिया जाता है। यदि आप बाद में उस एक्सपोर्ट किए गए चैनल APK पर थर्ड-पार्टी APK रीइन्फोर्समेंट, पैकिंग या री-साइनिंग टूल्स चलाते हैं, तो पोस्ट-प्रोसेसिंग चरण APK के क्रिप्टोग्राफ़िक सिग्नेचर को अमान्य कर सकता है या वेंडर के चैनल मेटाडेटा को ओवरराइट कर सकता है। अपने बेस APK को कंसोल पर अपलोड करने *से पहले* हमेशा उस पर R8 मिनिफ़िकेशन, हार्डनिंग, `zipalign` और साइनिंग पूरी करें, और एक्सपोर्ट किए गए चैनल APK को `apksigner verify --verbose` के साथ सत्यापित करें।

सारांश और रिलीज़ बिल्ड सत्यापन चेकलिस्ट

डीबग टेस्टिंग से प्रोडक्शन रिलीज़ बिल्ड में संक्रमण करते समय साइलेंट एट्रिब्यूशन रिग्रेशन को रोकने के लिए यह समझना आवश्यक है कि मोबाइल SDK को Android ProGuard और R8 ऑबफ़स्केशन से कैसे बाहर रखा जाए। बंडल किए गए कंज़्यूमर नियमों को सत्यापित करके, आपके SDK आर्काइव के अंदर सटीक केस-सेंसिटिव क्लास पाथ से मेल खाने वाले संकीर्ण रूप से स्कोप किए गए -keep डायरेक्टिव लिखकर, Android चैनल पैकेजों के लिए अपलोड से पहले के बिल्ड क्रम का पालन करके, और रॉ DEX बाइटकोड के विरुद्ध R8 की डायग्नोस्टिक आउटपुट फ़ाइलों को क्रॉस-चेक करके, Android इंजीनियर deferred deep linking या पैरामीटर रीस्टोरेशन को बाधित किए बिना पूर्ण कोड श्रिंकिंग बनाए रख सकते हैं।

Google Play पर मिनिफ़ाइड Android रिलीज़ बिल्ड प्रकाशित करने या चैनल पैकेज एक्सपोर्ट करने से पहले, इस चार-चरणीय सत्यापन चेकलिस्ट को निष्पादित करें:

  • SDK आर्काइव और मर्ज किए गए कॉन्फ़िगरेशन का निरीक्षण करें: सटीक क्लास पाथ और बंडल किए गए कंज़्यूमर नियमों का निरीक्षण करने के लिए jar tf या unzip -l के साथ अपने डाउनलोड किए गए SDK आर्काइव (जैसे v2.1.0) की जांच करें, और ./gradlew :app:analyzeReleaseR8Config (AGP 9.3+ में) चलाएं या configuration.txt की समीक्षा करें।

  • R8 रिपोर्ट और रॉ DEX आइडेंटिफ़ायर को क्रॉस-चेक करें: पुष्टि करें कि आवश्यक SDK एंट्री पॉइंट्स, रिफ्लेक्टिव <init>() कंस्ट्रक्टर्स, OpoData मॉडल फ़ील्ड्स, ResultCallBack मेथड्स, और JNI सिग्नेचर seeds.txt में दिखाई देते हैं, usage.txt से अनुपस्थित हैं, और रॉ apkanalyzer dex packages आउटपुट (--proguard-mappings के बिना चलाया गया) तथा mapping.txt में अपने मूल नाम बनाए रखते हैं।

  • अपलोड से पहले मिनिफ़िकेशन लागू करें और चैनल APK सिग्नेचर सत्यापित करें: Android चैनल पैकेज एक्सपोर्ट करने के लिए बेस APK को अपलोड करने से पहले उस पर सभी R8 मिनिफ़िकेशन, कोई भी थर्ड-पार्टी हार्डनिंग, zipalign (zipalign -c -P 16 -v 4), और APK साइनिंग पूरी करें, और एक्सपोर्ट किए गए पैकेजों पर apksigner verify --verbose चलाएं।

  • फ़िज़िकल-डिवाइस रिलीज़ स्मोक टेस्ट निष्पादित करें: एक वास्तविक Android डिवाइस पर साइन किए गए, मिनिफ़ाइड रिलीज़ APK को इंस्टॉल करें और H5 पैरामीटर इंस्टॉलेशन (getInstallParam) और वन-क्लिक वेकअप (handleDeepLink) दोनों को सत्यापित करें।

इंजीनियरिंग टीमें चैनल-पैकेज एक्सपोर्ट का परीक्षण करने और रिलीज़-बिल्ड पैरामीटर रीस्टोरेशन को सत्यापित करने के लिए OpoInstall डेवलपर कंसोल पर एक एप्लिकेशन पंजीकृत कर सकती हैं और अपना ऑबफ़स्केटेड बेस APK अपलोड कर सकती हैं।

संबंधित सामग्री

Share this article