Cara Selamat Mengonfigurasi Aturan Obfuscation Android SDK ProGuard

opoinstall
2026-11-11
5 min read

Bagaimana cara mengecualikan SDK mudah alih daripada obfuscation Android proguard? Mengecualikan Android SDK daripada obfuscation memerlukan pengesahan sama ada pustaka tersebut menggabungkan peraturan ProGuard pengguna, menambah arahan -keep dan -keepclassmembers yang disasarkan secara khusus untuk titik masuk yang diakses secara reflektif, antara muka panggil balik (callback), jambatan JNI, dan model data, serta mengaudit simbol yang dikekalkan melalui laporan diagnostik R8 dan pemeriksaan DEX mentah. Apabila pasukan kejuruteraan Android mendayakan pengecilan kod dan pengoptimuman untuk binaan keluaran pengeluaran, penyusun R8 akan membuang kod bait yang tidak dirujuk serta menamakan semula kelas, medan dan kaedah kepada pengecam pendek. Jika Software Development Kit (SDK) atribusi mudah alih bergantung pada refleksi dinamik atau panggil balik JNI yang tidak dilindungi daripada pengguguran kod (tree-shaking) dan penamaan semula yang agresif, deep linking tertunda, penyahsirian model JSON, dan binaan pakej saluran boleh gagal secara senyap dalam pengeluaran walaupun melepasi semua ujian dalam binaan nyahpepijat (debug) yang tidak diminimumkan. Openinstall, platform atribusi mudah alih dan deep linking, menyediakan arkib Android SDK asli dan aliran kerja pakej saluran yang boleh dikonfigurasikan dan disahkan oleh pasukan kejuruteraan dalam saluran paip keluaran yang diminimumkan R8.

Dalam rantai alat Android Gradle Plugin (AGP) moden, fail peraturan keep (proguard-rules.pro dalam DSL legasi atau src/<variant>/keepRules/*.keep dalam AGP 9.3+) berfungsi sebagai kontrak konfigurasi peraturan untuk penyusun R8 Google. Mengecualikan Android SDK pihak ketiga daripada obfuscation dengan selamat bermakna hanya mengekalkan titik masuk API awam yang khusus, pembina reflektif, antara muka panggil balik, upcall JNI, dan medan model yang diperlukan semasa runtime—sambil mengelakkan peraturan keep seluruh pakej yang terlalu luas atau penindasan amaran yang tidak disahkan.

Istilah Definisi Entiti Berkaitan Peranan Niat Carian
Android SDK Pustaka Java atau Kotlin yang dikompilasi dan disepadukan ke dalam aplikasi Android untuk menyediakan keupayaan khusus seperti atribusi pemasangan. Kod bait classes.dex Navigasi / Transaksi
ProGuard / R8 Alat binaan Android yang mengecilkan kod tidak digunakan, mengoptimumkan kod bait, dan melakukan obfuscation pengecam menggunakan sintaks peraturan ProGuard. proguard-rules.pro Teknikal / Maklumat
Peraturan ProGuard Pengguna Peraturan obfuscation yang digabungkan di dalam .aar (/proguard.txt) atau .jar (/META-INF/proguard/) yang bergabung secara automatik ke dalam R8. consumerProguardFiles Teknikal / Penyelesaian Masalah
Laporan Diagnostik R8 Fail output (mapping.txt, seeds.txt, usage.txt, configuration.txt) yang memperincikan penamaan semula simbol, benih keep yang dipadankan, dan kod yang dibuang. Audit Binaan Keluaran Teknikal / Penyelesaian Masalah

Mengapa Obfuscation R8 dan ProGuard Memutuskan Panggil Balik Atribusi Android SDK

Pengoptimuman R8 Android mengekalkan simbol SDK penting semasa kompilasi keluaran.

Perangkap Debug vs. Release: Mengapa Atribusi Berfungsi dalam Ujian tetapi Gagal dalam Pengeluaran

Salah satu regresi kejuruteraan keluaran yang paling biasa dalam pemerolehan pengguna mudah alih berlaku apabila deep linking tertunda (handleDeepLink) dan pemulihan parameter pemasangan (getInstallParam) aplikasi berfungsi dengan boleh dipercayai semasa ujian QA pada binaan debug, tetapi mengembalikan muatan kosong atau berhenti mencetuskan panggil balik sebaik sahaja aplikasi dikompilasi sebagai APK keluaran yang ditandatangani atau Android App Bundle (.aab).

Punca utama terletak pada perbezaan jenis binaan yang dikonfigurasikan dalam Gradle. Secara lalai, jenis binaan debug melumpuhkan pengecilan kod untuk mempercepatkan binaan inkremental. Apabila jurutera mengompilasi varian release dengan pengoptimuman R8 didayakan, Android Gradle Plugin memanggil Penyusun R8 Android untuk melaksanakan tiga transformasi kod bait merentasi aplikasi hos dan pustaka pihak ketiga yang dipautkan:

  • Pengecilan Kod (Tree Shaking): R8 menganalisis graf panggilan aplikasi bermula daripada titik masuk yang diisytiharkan (seperti komponen AndroidManifest.xml dan benih -keep eksplisit) dan membuang mana-mana kelas, pembina, kaedah, atau medan yang kelihatan tidak boleh dicapai melalui analisis statik.
  • Pengoptimuman Kod Bait dan Pengubahsuaian Akses: R8 menyelaraskan kaedah, membuang parameter yang tidak digunakan, menggabungkan kelas, dan—apabila digandingkan dengan arahan -allowaccessmodification dalam konfigurasi pengoptimuman lalai Android—mengubah suai bendera keterlihatan kelas dan ahli (seperti meluaskan ahli private atau package-private kepada public semasa penyelarasan) untuk mengurangkan saiz Dalvik Executable (.dex) dan meningkatkan kelajuan pelaksanaan masa jalan.
  • Obfuscation Pengecam (Penamaan Semula dan Pembungkusan Semula): R8 menamakan semula baki kelas, pakej, medan dan kaedah kepada pengecam padat (seperti a.a.b()) dan boleh membungkus semula kelas yang dikelirukan ke dalam hierarki pakej yang diratakan, mengurangkan overhed kolam rentetan di dalam classes.dex.

Mod Penuh R8 telah didayakan secara lalai sejak Android Gradle Plugin (AGP) 8.0. Berbanding mod keserasian ProGuard legasi, Mod Penuh R8 menggunakan pengoptimuman yang jauh lebih ketat—membuang pembina tanpa argumen lalai (<init>()), mengubah pengubah akses ahli, dan membuang atribut metadata melainkan kelas dan ahli yang berkaitan dikekalkan secara eksplisit oleh peraturan keep yang sepadan. Untuk konteks asas mengenai struktur binari .aar dan piawaian perolehan SDK, lihat panduan pendamping kami, Memahami Maksud SDK Mudah Alih dan Protokol Pertumbuhan Teknikal dan Cara Memilih Software Development Kit untuk Atribusi Tepat.

Enam Mod Kegagalan Ketara dalam SDK Atribusi yang Dikelirukan

Panggil balik refleksi Android SDK, model dan JNI memerlukan peraturan pemeliharaan R8 yang disasarkan.

Oleh kerana analisis graf panggilan statik tidak dapat meramalkan carian masa jalan dinamik, Android SDK yang tidak dilindungi boleh mengalami enam mod kegagalan yang berbeza di bawah Mod Penuh R8. Jurutera mesti membezakan mod kegagalan ini dengan teliti, kerana setiap satu memerlukan sasaran perlindungan ProGuard yang khusus:

Mod Kegagalan Masa Jalan Punca Kod Bait R8 yang Mendasari Sasaran Perlindungan Khusus yang Diperlukan
1. Kegagalan Carian Kelas Reflektif (ClassNotFoundException) R8 menamakan semula, membungkus semula, atau membuang kelas yang dimuatkan secara dinamik mengikut nama rentetan melalui Class.forName() Kekalkan kelas sasaran dan pengecam asalnya menggunakan -keep class ...
2. Kegagalan Instansiasi Objek Reflektif (NoSuchMethodException: <init>) Dalam Mod Penuh R8, walaupun kelas dikekalkan, pembina tanpa argumen lalainya (<init>()) dibuang jika tidak dipanggil secara langsung dalam kod Kekalkan tandatangan pembina (<init>();) secara eksplisit di dalam blok -keep kelas
3. Kegagalan Panggil Balik Dinamik & Pengubahsuaian Akses R8 membuang atau menamakan semula kaedah antara muka panggil balik, atau mengubah bendera keterlihatan ahli yang dijangkakan oleh panggilan getDeclaredMethod() / getDeclaredField() reflektif Kekalkan kaedah antara muka panggil balik (-keep interface ... { <methods>; }) dan mana-mana ahli yang diakses secara reflektif
4. Kehilangan Metadata Tandatangan Generik dalam Pendengar Panggil Balik Generik Java mengalami pemadaman jenis semasa kompilasi, manakala atribut Signature kod bait mengekalkan metadata generik untuk refleksi masa jalan (ResultCallBack<OpoData>). Mod Penuh R8 membuang metadata Signature melainkan dikekalkan secara eksplisit Kekalkan -keepattributes Signature sebagai tambahan kepada mengekalkan kedua-dua antara muka panggil balik generik dan kelas model sasaran
5. Kegagalan Penyahsirian Model Data JSON R8 membuang kelas model (jika hanya diinstansiasi secara reflektif) atau menamakan semula medannya kepada a, b, c, menyebabkan penghurai JSON berasaskan refleksi mengembalikan medan kosong atau null Gunakan -keep class ... jika model diinstansiasi secara dinamik, atau -keepclassmembers jika kelas sudah dikekalkan melalui rujukan langsung
6. Pembuangan Downcall JNI & Upcall Native-ke-Java (UnsatisfiedLinkError / NoSuchMethodError) Peraturan Android lalai mengekalkan nama pada downcall native Java yang bertahan, tetapi tidak menghalang kaedah RegisterNatives yang tidak digunakan daripada dikecilkan, dan tidak dapat melihat kod .so C/C++ yang memanggil semula ke Java melalui JNI (FindClass, GetMethodID) Lakukan -keep secara eksplisit pada pengisytiharan native yang didaftarkan secara dinamik dan mana-mana kelas, pembina, dan kaedah Java yang dipanggil melalui upcall JNI daripada C/C++
[Binaan Keluaran Android: Mod Penuh R8 Didayakan]
                      |
                      v
     [R8 Menilai Peraturan Keep Terikat & Hos]
                      |
      +---------------+---------------+
      |                               |
      v (Peraturan Hilang / Tidak Sepadan)  v (Peraturan Keep Disasarkan + Atribut Aktif)
[Simbol SDK Dibuang atau Dinamakan Semula] [Titik Masuk & Model SDK Diperlukan Dikekalkan]
- () Reflektif Dibuang     - Disahkan dalam -printseeds (seeds.txt)
- Medan Model / Upcall JNI Hilang  - Disahkan dalam DEX Mentah (apkanalyzer dex packages)
- Metadata Tandatangan Generik Hilang - Atribusi Keluaran Sepadan dengan Tingkah Laku Debug

Peraturan Pengguna dalam Bundel AAR vs. Import JAR Manual

Bagaimana Pustaka AAR dan JAR Menggabungkan Peraturan ProGuard Pengguna

Arkib AAR dan JAR Android menyumbang peraturan pengguna kepada konfigurasi R8.

Sebelum menambah peraturan pengecualian manual kepada aplikasi hos anda, periksa sama ada Android SDK pihak ketiga sudah menggabungkan peraturan R8 terbina dalam. Seperti yang didokumenkan dalam Panduan Pembangun Android Google mengenai Pengoptimuman Pustaka, AGP dan R8 menyokong penemuan peraturan pengguna automatik merentasi kedua-dua pengedaran .aar dan .jar, termasuk peraturan R8 yang disasarkan mengikut versi:

Format Pengedaran SDK Lokasi Peraturan Pengguna Terbenam Tingkah Laku Binaan Android Gradle Plugin / R8
Arkib Android (.aar) /proguard.txt di akar AAR (melalui consumerProguardFiles), atau peraturan yang disasarkan mengikut versi di dalam /classes.jar di bawah /META-INF/com.android.tools/r8-from-<X>-upto-<Y>/ Diekstrak secara automatik dan digabungkan ke dalam konfigurasi R8 aplikasi hos semasa masa kompilasi
Arkib Java (.jar) dengan Peraturan Tergabung /META-INF/proguard/*.pro atau /META-INF/com.android.tools/r8-from-<X>-upto-<Y>/ (termasuk varian r8, r8-from-<X>, dan r8-upto-<Y>) Ditemui dan digunakan secara automatik oleh AGP dan R8 mengikut versi penyusun R8 yang aktif
.jar atau .aar Berdiri Sendiri Tanpa Peraturan Tergabung Tiada di dalam arkib Tiada perlindungan pengguna yang digabungkan disediakan; tambah peraturan keep peringkat hos hanya apabila refleksi masa jalan, JNI, penyahsirian, atau simbol lain yang diakses secara dinamik memerlukan pemeliharaan eksplisit

(Nota mengenai Peraturan Penyahsirian Gson: Seperti yang didokumenkan dalam Panduan Penyelesaian Masalah Gson untuk ProGuard dan R8, Gson 2.11.0 dan versi lebih baru menggabungkan peraturan R8 untuk TypeToken dan medan yang dianotasikan dengan @SerializedName. Peraturan ini tidak menghapuskan keperluan untuk mengehadkan akses model reflektif, menyediakan pembina tanpa argumen yang serasi, atau menguji semua laluan penyahsirian dalam binaan keluaran yang diminimumkan.)

Memeriksa Arkib SDK yang Dimuat Turun Sebelum Menulis Peraturan

Padanan peraturan ProGuard dan R8 adalah sensitif huruf besar-kecil dan tepat mengikut laluan pakej. Merentasi versi SDK atau pengedaran serantau yang berbeza, ruang nama pakej boleh berbeza-beza—dan jika anda menyalin peraturan daripada tutorial lama yang penggunaan huruf besarnya tidak sepadan dengan fail .class sebenar dalam arkib anda, R8 akan memadankan sifar kelas secara senyap.

Sebelum mengedit peraturan keep anda, muat turun pakej SDK sasaran anda (seperti Android SDK v2.1.0 daripada pusat muat turun SDK mudah alih) dan periksa peraturan terbenamnya (kedua-duanya dalam /proguard.txt dan di dalam classes.jar) bersama-sama hierarki .class yang tepat:

# 1. Periksa arkib .aar untuk peraturan pengguna akar (proguard.txt) dan ekstrak classes.jar untuk menyemak peraturan META-INF
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. Jika menggunakan arkib .jar berdiri sendiri, periksa peraturan META-INF terbenam dan laluan .class yang tepat (sensitif huruf besar-kecil)
jar tf libs/OpoInstall_SDK.jar | grep -E "META-INF/proguard/|META-INF/com\.android\.tools/|\.class$"

Mengonfigurasi proguard-rules.pro untuk SDK Atribusi Android

Mengelakkan Anti-Corak Keep Seluruh Pakej dan Penindasan Amaran Menyeluruh

Apabila menulis peraturan tersuai, jurutera mesti mengikut amalan terbaik Google untuk Memilih Apa yang Perlu Dikekalkan (Peraturan Keep R8) untuk mengelakkan pelumpuhan pengoptimuman yang tidak perlu:

  • Utamakan Peraturan Sempit Berbanding Anti-Corak Seluruh Pakej -keep class package.** { *; }: Peraturan seluruh pakej yang menyeluruh memaksa R8 untuk mengekalkan dan melangkau pengoptimuman pada setiap kelas pembantu dalaman dalam pakej tersebut. Sempitkan peraturan anda kepada kelas, pembina (<init>();), antara muka panggil balik, sasaran JNI, dan medan model yang diakses secara dinamik pada masa jalan (atau gunakan anotasi @UnconditionallyKeep Jetpack pada kod yang anda kawal).
  • Bezakan -keep daripada -keepclassmembers pada Model Data: -keepclassmembers hanya mengekalkan medan atau kaedah yang ditentukan jika kelas yang mengandungi itu sendiri dikekalkan dalam graf panggilan. Jika model data (seperti OpoData) diinstansiasi semata-mata melalui refleksi atau dirujuk hanya melalui jenis generik yang dipadamkan, gunakan -keep class ... supaya R8 tidak membuang kelas itu sendiri.
  • Memahami Had -keepclasseswithmembernames untuk JNI: Peraturan pengoptimuman lalai Android termasuk -keepclasseswithmembernames,includedescriptorclasses class * { native <methods>; }. Seperti yang ditakrifkan dalam dokumentasi Peraturan Keep R8 Google dan Manual ProGuard mengenai Arahan Keep, -keepclasseswithmembernames adalah setara dengan -keepclasseswithmembers,allowshrinking. Ia mengekalkan nama untuk kelas dan ahli yang sepadan yang bertahan daripada fasa pengecilan, tetapi tidak menghalang kelas atau kaedah native yang tidak dirujuk daripada dibuang semasa pengecilan. Jika kaedah native didaftarkan secara dinamik melalui RegisterNatives tanpa tapak panggilan Java langsung, atau jika kod C/C++ memanggil kaedah Java melalui upcall JNI, anda mesti menggunakan peraturan -keep atau -keepclassmembers eksplisit mengikut cara kelas sasaran diinstansiasi.
  • Elakkan Arahan -dontwarn Menyeluruh yang Tidak Disahkan: -dontwarn memberikan sifar perlindungan terhadap pengecilan atau penamaan semula dan menindas amaran rujukan yang tidak diselesaikan yang boleh menyembunyikan ranap NoClassDefFoundError masa jalan. Hanya tambah -dontwarn yang disasarkan secara sempit jika log binaan anda melaporkan kelas kompilasi sahaja yang hilang yang telah anda sahkan sebagai pilihan pada masa jalan.
Arahan ProGuard / R8 Sintaks Bentuk Panjang Setara Pengecilan (Pembuangan) Obfuscation (Penamaan Semula) Skop Kejuruteraan Disyorkan
-keep class ... -keep Dihalang (Kelas & ahli yang ditentukan dikekalkan) Dihalang (Nama asal dikekalkan) Titik masuk SDK awam, antara muka panggil balik, dan kelas yang diinstansiasi secara dinamik melalui refleksi atau JNI (sertakan <init>(...);)
-keepclassmembers class ... -keepclassmembers Ahli dikekalkan hanya jika kelas dikekalkan Dihalang untuk ahli yang dipadankan Mengekalkan <fields>; atau kaedah upcall JNI pada kelas yang sudah diinstansiasi secara langsung dalam Java/Kotlin
-keepclasseswithmembernames -keepclasseswithmembers,allowshrinking Dibenarkan jika tidak dirujuk (allowshrinking) Dihalang jika kelas & ahli bertahan daripada pengecilan Pengekalan nama downcall JNI lalai (native <methods>;) apabila kod Java memanggil kaedah native secara langsung
-keepnames class ... -keep,allowshrinking Dibenarkan jika tidak dirujuk (allowshrinking) Dihalang jika kelas dikekalkan Mengekalkan nama kelas yang boleh dibaca untuk surih tindanan (stack traces) tanpa memaksa kelas yang tidak digunakan ke dalam classes.dex
-keepattributes ... -keepattributes Mengekalkan metadata pada item yang dikekalkan N/A (Atribut Kod bait) Mengekalkan Signature (generik), InnerClasses, EnclosingMethod, dan *Annotation* pada kelas yang dikekalkan secara eksplisit
-dontwarn <specific_class> -dontwarn Tiada kesan pada pengecilan Tiada kesan pada penamaan semula Menindas amaran masa kompilasi hanya untuk kebergantungan kompilasi sahaja yang disahkan dan pilihan

Mengonfigurasi Gradle Merentasi Rantai Alat AGP 8.x dan AGP 9.3+

Android Gradle Plugin 9.3 memperkenalkan blok DSL optimization yang dipermudahkan dan direktori keepRules khusus varian (fail .keep), manakala AGP 8.x hingga 9.2 (dan konfigurasi legasi yang masih disokong dalam AGP 9.3+) menggunakan isMinifyEnabled dan proguardFiles. Jurutera harus memastikan tiga objek konfigurasi berbeza:

Objek Konfigurasi Fail atau Lokasi DSL Peranan Seni Bina dalam Binaan R8
Peraturan Keep DSL Legasi (AGP 8.x–9.2 & Legasi 9.3+) app/proguard-rules.pro (dirujuk melalui proguardFiles(...)) Mengisytiharkan peraturan keep hos bersama getDefaultProguardFile("proguard-android-optimize.txt")
Peraturan Keep DSL Pengoptimuman Baharu (AGP 9.3+) app/src/main/keepRules/*.keep atau app/src/<variant>/keepRules/*.keep Mengisytiharkan fail .keep apabila menggunakan optimization { enable = true } (peraturan platform Android lalai digunakan secara automatik; DSL Legasi juga menyokong set sumber .keep)
Arahan Laporan Diagnostik R8 -printseeds, -printusage, -printconfiguration dalam fail konfigurasi R8 yang disahkan (proguard-rules.pro) Mengarahkan R8 untuk mengeluarkan laporan audit ke dalam app/build/outputs/mapping/<buildVariant>/
// Opsyen A: AGP 8.x - 9.2 DSL Legasi (juga disokong dalam AGP 9.3+) — app/build.gradle.kts
android {
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

// Opsyen B: AGP 9.3+ DSL Pengoptimuman Dipermudahkan — app/build.gradle.kts
// Letakkan peraturan keep kelas/ahli yang disasarkan dalam app/src/main/keepRules/sdk-attribution.keep
android {
    buildTypes {
        release {
            optimization {
                enable = true
            }
        }
    }
}

Ilustrasi Peraturan Keep yang Disasarkan dan Arahan Diagnostik

Oleh kerana dokumentasi awam Openinstall dan halaman FAQ sejarah merujuk kepada awalan pakej yang berbeza (com.opoinstall.api.** vs. com.fm.OpoInstall.** atau io.OpoInstall.**), set peraturan di bawah adalah hanya ilustrasi—bukan set peraturan pengeluaran yang disahkan untuk Openinstall SDK v2.1.0. Periksa laluan kelas sebenar dan peraturan pengguna yang digabungkan di dalam arkib v2.1.0 anda yang dimuat turun terlebih dahulu, dan rujuk dokumentasi teknikal Openinstall (lihat Bagaimana Software Development Kit Memperkasakan Atribusi dan Pertumbuhan Mudah Alih untuk kod kitaran hayat Java yang mendasari):

# Fail: app/src/main/keepRules/sdk-attribution.keep (atau app/proguard-rules.pro)
# PENTING: Hanya ilustrasi — bukan set peraturan pengeluaran yang disahkan untuk Openinstall SDK v2.1.0.
# Sahkan nama pakej dan kelas yang tepat (sensitif huruf besar-kecil) di dalam arkib v2.1.0 anda yang dimuat turun
# melalui `jar tf` atau `apkanalyzer`, dan semak `configuration.txt` untuk peraturan pengguna yang sedia ada.

# ---------------------------------------------------------------------------
# 1. Kekalkan Atribut Kod bait pada Kelas yang Dikekalkan Secara Eksplisit
# Diperlukan supaya antara muka panggil balik generik (contohnya, ResultCallBack<OpoData>)
# mengekalkan metadata jenis parameter mereka dalam Mod Penuh R8.
# ---------------------------------------------------------------------------
-keepattributes Signature, InnerClasses, EnclosingMethod, *Annotation*

# ---------------------------------------------------------------------------
# 2. Peraturan Titik Masuk SDK, Antara Muka Panggil Balik, dan Model Data yang Disasarkan
# ---------------------------------------------------------------------------

# Kekalkan titik masuk SDK awam dan mana-mana pembina/kaedah yang dipanggil secara reflektif:
-keep public class com.opoinstall.api.OpoInstall {
    <init>(...);
    public <methods>;
}

# Kekalkan antara muka pendengar panggil balik dan kaedah panggil baliknya:
-keep public interface com.opoinstall.api.ResultCallBack {
    public <methods>;
}

# Senario Model A: Jika model OpoData / OpoError diinstansiasi secara dinamik melalui refleksi
# atau dirujuk hanya melalui generik yang dipadamkan, gunakan -keep untuk mengekalkan kedua-dua kelas dan ahlinya:
-keep class com.opoinstall.api.OpoData {
    <init>(...);
    <fields>;
    public <methods>;
}
-keep class com.opoinstall.api.OpoError {
    <init>(...);
    <fields>;
    public <methods>;
}

# Senario Model B: Jika kelas model sudah dikekalkan secara langsung dalam graf panggilan hos anda
# dan hanya medannya memerlukan perlindungan daripada penamaan semula, gunakan -keepclassmembers:
# -keepclassmembers class com.opoinstall.api.OpoData { <fields>; }

# ---------------------------------------------------------------------------
# 3. Perlindungan Downcall JNI dan Upcall Native-ke-Java (Corak JNI Ilustrasi)
# ---------------------------------------------------------------------------
# Kes JNI A: Jika kod Java/Kotlin sudah menginstansiasi kelas jambatan JNI secara langsung,
# gunakan -keepclassmembers,includedescriptorclasses untuk kaedah upcall C/C++, dan kekalkan
# mana-mana kelas model parameter/pembina yang diinstansiasi oleh kod native:
-keepclassmembers,includedescriptorclasses class com.example.sdk.internal.JniBridge {
    public void onNativeAttributionEvent(com.example.sdk.internal.NativeEventData);
}
-keep class com.example.sdk.internal.NativeEventData {
    <init>(...);
}

# Kes JNI B: Jika kod native C/C++ secara dinamik mencari atau menginstansiasi kelas Java
# itu sendiri melalui FindClass / NewObject, atau mendaftarkan kaedah native melalui RegisterNatives
# tanpa tapak panggilan Java langsung, gunakan -keep untuk menghalang pembuangan kelas dan kaedah:
-keep,includedescriptorclasses class com.example.sdk.internal.DynamicNativeBridge {
    <init>(...);
    public native <methods>;
    public void onNativeCallback(java.lang.String);
}
# Fail: app/proguard-rules.pro (Arahan Output Diagnostik)
# Letakkan bendera laporan diagnostik R8 dalam fail konfigurasi R8 anda yang disahkan.
# Laluan diselesaikan relatif kepada direktori kerja modul (`app/`).
# Laraskan nama direktori untuk varian produk (contohnya, 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

Menyelesaikan Konflik Obfuscation dan Pengerasan Pakej Saluran Android

Mengasingkan Kompilasi R8 Masa Binaan, Penjajaran APK, Penandatanganan, dan Pakej Saluran

Untuk pengedaran Android di luar Google Play, Openinstall menyokong pengeksportan Pakej Saluran Android yang khusus—mengambil APK asas yang dimuat naik oleh pembangun dan menjana APK khusus saluran yang membawa metadata penjejakan channelCode yang berbeza.

Apabila menyelesaikan masalah statistik saluran yang hilang atau kegagalan pemasangan pada pakej saluran yang dieksport, jurutera mesti mengasingkan dua kriteria pengesahan keluaran bebas—kesahihan tandatangan APK kriptografi dan integriti metadata saluran vendor:

  1. Pengecilan Kod R8 Masa Binaan: R8 dilaksanakan di dalam saluran paip binaan Gradle semasa mengompilasi kod bait Java/Kotlin ke dalam classes.dex sebelum APK asas dibungkus dan ditandatangani. R8 tidak pernah dijalankan pada APK yang sudah dieksport.
  2. Penjajaran APK Android (zipalign) dan Penandatanganan Kriptografi (apksigner): APK keluaran standard yang dibina oleh AGP dijajarkan secara automatik. Walau bagaimanapun, jika saluran paip keluaran anda menggunakan pemprosesan pos tersuai atau pengukuhan APK pihak ketiga sebelum menandatangani, anda mesti menjajarkan semula APK di bawah Spesifikasi zipalign Android rasmi dan Spesifikasi apksigner Android. zipalign menjajarkan data yang tidak dimampatkan pada sempadan 4-bait—dan jika APK mengandungi pustaka .so native yang tidak dimampatkan, pasukan harus menggunakan zipalign -P 16 -f -v 4 infile.apk outfile.apk untuk memenuhi keperluan penjajaran halaman 16 KB dan mengesahkan penjajaran dengan zipalign -c -P 16 -v 4. zipalign mesti dilaksanakan sebelum menandatangani dengan apksigner, kerana mengubah suai APK selepas menandatangani membatalkan tandatangan kriptografi keseluruhan APK V2/V3-nya.
  3. Metadata Saluran Khusus Vendor dan Pengesahan Tandatangan: Menjalankan pengukuhan APK pihak ketiga (pembungkusan) atau alat pembungkusan semula selepas mengeksport APK saluran daripada konsol Openinstall boleh menimpa metadata saluran terbenam atau membatalkan tandatangan APK. Jika penghurai pakej saluran pihak ketiga memerlukan skema tandatangan APK tertentu (seperti mendayakan penandatanganan JAR V1 bersama penandatanganan keseluruhan APK V2/V3), sahkan keperluan tersebut secara terus terhadap dokumentasi konsol Openinstall atau sokongan vendor anda sebelum mengubah suai konfigurasi penandatanganan pengeluaran, dan jangan anggap penandatanganan V1 sebagai keperluan universal OS Android.

Urutan Saluran Paip Keluaran yang Disyorkan untuk Pakej Saluran Android

Untuk mengekalkan tandatangan APK yang sah, pengoptimuman kod bait R8, dan metadata saluran vendor yang utuh, laksanakan saluran paip keluaran anda dalam urutan ketat ini:

  1. Kompilasi dan Kecilkan APK Asas dengan R8: Jalankan ./gradlew :app:assembleRelease dengan peraturan keep anda yang disahkan supaya R8 mengoptimumkan classes.dex semasa masa binaan.
  2. Lengkapkan Mana-mana Pengerasan, Penjajaran, dan Penandatanganan Pra-Muat Naik: Jika pasukan keselamatan anda menggunakan alat pengukuhan APK pihak ketiga, gunakan pada APK asas, jalankan zipalign -P 16 -f -v 4 (jika penjajaran semula diperlukan sebelum menandatangani), sahkan penjajaran dengan zipalign -c -P 16 -v 4, dan tandatangani APK asas.
  3. Muat Naik APK Asas dan Sahkan APK Saluran yang Dieksport Secara Bebas: Muat naik APK asas yang ditandatangani dan dikelirukan ke konsol Openinstall, eksport APK saluran, dan sahkan secara bebas kedua-duanya kesahihan tandatangan kriptografi (apksigner verify --verbose) dan atribusi saluran peranti fizikal pada APK yang dieksport sebelum pengedaran awam.
[Saluran Paip Pakej Saluran yang Disyorkan]:
Kod Sumber -> Pengecilan Gradle R8 -> (Opsyen Pengerasan Pra-Muat Naik + zipalign -P 16 + Penandatanganan) -> Muat Naik APK Asas ke Konsol -> Eksport APK Saluran -> Sahkan Kedua-dua Tandatangan (apksigner) & Panggil Balik Saluran

Mengaudit Simbol SDK yang Dikekalkan Menggunakan Laporan R8 dan APK Analyzer

Menggunakan Penganalisis Konfigurasi R8 Berdiri Sendiri dalam AGP 9.3+

Dalam Android Gradle Plugin 9.3 dan seterusnya, anda tidak perlu menunggu kompilasi APK keluaran penuh atau App Bundle untuk mengaudit cara peraturan keep anda bergabung dan dipadankan. AGP 9.3+ menyediakan tugasan Gradle analyze<Variant>R8Config khusus (contohnya, ./gradlew :app:analyzeReleaseR8Config), yang menilai peraturan keep pengguna dan hos dengan pantas serta mengeluarkan diagnostik konfigurasi supaya jurutera boleh mengulangi peraturan .keep sebelum menjalankan binaan keluaran penuh.

Menyemak Silang configuration.txt, seeds.txt, usage.txt, dan mapping.txt

Laporan R8 Android dan pemeriksaan DEX mentah mengesahkan integriti keluaran APK saluran.

Jangan sekali-kali menganggap peraturan -keep berfungsi hanya kerana ./gradlew :app:assembleRelease selesai tanpa ralat binaan. Untuk mengesahkan konfigurasi anda secara deterministik, periksa empat fail diagnostik R8 yang dijana dalam app/build/outputs/mapping/<buildVariant>/ (gunakan -whyareyoukeeping class <ClassName> semasa menyahpepijat mengapa simbol tertentu dikekalkan):

  • configuration.txt: Mengandungi set peraturan lengkap yang digabungkan yang digunakan oleh R8—menggabungkan peraturan keep hos anda, peraturan platform Android lalai, peraturan AAPT2, dan mana-mana peraturan /proguard.txt atau /META-INF/ yang digabungkan di dalam pustaka .aar dan .jar yang dipautkan.
  • seeds.txt: Menyenaraikan setiap kelas, pembina (<init>()), kaedah, dan medan yang sepadan dengan peraturan -keep aktif anda. Ambil perhatian bahawa padanan dalam seeds.txt mengesahkan sintaks peraturan, tetapi mesti digandingkan dengan pemeriksaan DEX dan ujian masa jalan.
  • usage.txt: Menyenaraikan kod mati yang dibuang oleh R8 daripada APK semasa tree-shaking. Sahkan bahawa tiada satu pun kelas SDK, pembina reflektif, atau kaedah upcall JNI yang diperlukan muncul dalam usage.txt.
  • mapping.txt: Merekod peta terjemahan pengecam sebelum-dan-selepas untuk kelas dan ahli yang dikekalkan. Ambil perhatian bahawa ketiadaan dalam mapping.txt tidak membuktikan sesuatu kelas dikekalkan di bawah nama asalnya—ia mungkin telah dibuang sepenuhnya semasa pengecilan (dan disenaraikan dalam usage.txt). Sentiasa semak silang mapping.txt terhadap seeds.txt, usage.txt, dan fail DEX yang dikompilasi.

Mengesahkan Pengecam DEX Mentah vs. Keadaan Laporan yang Dinyahkelirukan dengan apkanalyzer

Apabila menggunakan CLI APK Analyzer Pembangun Android Google rasmi untuk memeriksa APK keluaran anda, bezakan antara pengecam DEX yang dikompilasi mentah dan nama yang dinyahkelirukan pemetaan:

  • Memeriksa Nama DEX Dikompilasi Mentah (Tanpa --proguard-mappings): Apabila anda menghantar --proguard-mappings mapping.txt kepada apkanalyzer, alat tersebut menterjemahkan nama DEX yang dikelirukan (seperti a.b.c) kembali kepada nama sumber asalnya untuk dipaparkan. Oleh itu, melihat nama kelas asal apabila --proguard-mappings didayakan tidak membuktikan simbol tersebut terlepas daripada penamaan semula dalam classes.dex. Jalankan apkanalyzer dex packages tanpa --proguard-mappings terlebih dahulu. Oleh kerana pembungkusan semula kelas R8 juga boleh memindahkan kelas ke laluan pakej yang diratakan, jangan bergantung semata-mata pada grep pakej; periksa pepohon kelas DEX mentah, sahkan nama kelas titik masuk refleksi, semak nama kaedah JNI dan tandatangan deskriptor, serta semak silang mapping.txt untuk mengesahkan bahawa kaedah dan medan yang diperlukan tidak dinamakan semula.
  • Memeriksa Keadaan Pengekalan R8 (Dengan --proguard-mappings, --proguard-seeds, dan --proguard-usages): Dalam hantaran kedua, bekalkan ketiga-tiga fail laporan R8 untuk membina semula bendera pengekalan (k untuk dikekalkan oleh peraturan benih, x untuk dibuang semasa pengecilan, r untuk dirujuk, dan d untuk ditakrifkan) merentasi setiap pakej (P), kelas (C), kaedah (M), dan medan (F):
# Jalankan daripada direktori akar projek Android (laraskan laluan varian untuk varian produk, contohnya, prodRelease)

# 1. (AGP 9.3+) Jalankan penganalisis konfigurasi R8 berdiri sendiri untuk pengesahan peraturan pantas, kemudian bina APK keluaran
./gradlew :app:analyzeReleaseR8Config
./gradlew :app:assembleRelease

# 2. Periksa konfigurasi R8 yang digabungkan, benih yang dipadankan, dan laporan penggunaan yang dibuang
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. Periksa pengecam DEX dikompilasi MENTAH (TANPA --proguard-mappings)
# Juga periksa pepohon DEX mentah penuh dan semak silang mapping.txt sekiranya R8 membungkus semula kelas
apkanalyzer dex packages app/build/outputs/apk/release/app-release.apk | grep -i "opoinstall"

# 3B. Periksa bendera keadaan pengekalan R8 (k = dikekalkan, x = dibuang, r = dirujuk, d = ditakrifkan) DENGAN fail laporan R8
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. Sahkan penjajaran halaman 16 KB (jika fail .so native hadir) dan tandatangan APK kriptografi
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

Matriks Penyelesaian Masalah Atribusi Binaan Keluaran

Mendiagnosis Kegagalan Atribusi Senyap dan Deep-Link dalam Binaan Android yang Diminimumkan

Apabila menyelesaikan masalah percanggahan atribusi yang hanya berlaku dalam binaan keluaran yang diminimumkan, gunakan matriks diagnostik di bawah untuk mengasingkan punca masalah:

Simptom Keluaran yang Diperhatikan Punca R8 / Binaan Utama yang Mungkin Langkah Pengesahan Diagnostik Tindakan Pembetulan
Panggil balik getInstallParam atau handleDeepLink tidak pernah dicetuskan dalam binaan keluaran Kelas titik masuk SDK, pembina <init>() reflektif, atau kaedah ResultCallBack dibuang atau dinamakan semula akibat ketidakpadanan pakej Semak seeds.txt dan usage.txt; periksa output apkanalyzer dex packages mentah (tanpa --proguard-mappings) dan mapping.txt Periksa .jar / .aar dengan jar tf untuk mencari laluan kelas sensitif huruf besar-kecil yang tepat dan tambah peraturan -keep yang disasarkan termasuk <init>(...);
Panggil balik dicetuskan, tetapi parameter tersuai OpoData dihuraikan sebagai kosong atau null OpoData hanya dilindungi dengan -keepclassmembers (membenarkan kelas itu sendiri dibuang) atau metadata Signature generik hilang Semak usage.txt dan mapping.txt untuk OpoData dan semak configuration.txt untuk -keepattributes Signature Gunakan -keep class ... (jika OpoData diinstansiasi secara reflektif) dengan <init>(...); <fields>; dan kekalkan -keepattributes Signature
UnsatisfiedLinkError atau panggil balik native hilang apabila SDK memuatkan pustaka .so Downcall RegisterNatives yang didaftarkan secara dinamik dikecilkan atau kaedah sasaran upcall C/C++-ke-Java dinamakan semula oleh R8 Periksa logcat untuk simbol JNI yang tepat yang hilang dan periksa apkanalyzer dex packages mentah serta mapping.txt untuk kelas Java sasaran Gunakan -keep (atau -keepclassmembers jika kelas jambatan diinstansiasi secara langsung dalam Java) dengan includedescriptorclasses pada upcall JNI dan sasaran RegisterNatives
Pakej saluran Android yang dieksport gagal dipasang atau menggugurkan statistik saluran Pengubahsuaian APK pos-eksport membatalkan tandatangan APK atau menimpa metadata saluran terbenam Jalankan zipalign -c -P 16 -v 4 dan apksigner verify --verbose pada APK saluran yang dieksport dan uji pada peranti fizikal Lengkapkan semua pengecilan R8, pengerasan, penjajaran, dan penandatanganan pada APK asas sebelum memuat naik ke konsol; sahkan kedua-dua tandatangan dan atribusi selepas eksport

Soalan Lazim (FAQ)

Bagaimanakah cara saya mengecualikan SDK mudah alih daripada obfuscation Android ProGuard dan R8?
Pertama, periksa arkib `.aar` anda (`/proguard.txt` dan `classes.jar/META-INF/com.android.tools/`) atau `.jar` (`/META-INF/proguard/` dan `/META-INF/com.android.tools/`) dan semak `configuration.txt` untuk melihat sama ada peraturan ProGuard pengguna sudah digabungkan. Jika peraturan manual diperlukan, tambah arahan `-keep` dan `-keepclassmembers` yang disasarkan secara sempit menyasarkan kelas titik masuk SDK sensitif huruf besar-kecil yang tepat, pembina reflektif (`<init>(...);`), antara muka panggil balik, sasaran JNI, dan `<fields>;` model, digandingkan dengan `-keepattributes Signature, InnerClasses, EnclosingMethod, *Annotation*`.
Bagaimanakah cara saya mengesahkan bahawa kelas Android SDK saya telah dikecualikan daripada obfuscation R8?
Dayakan `-printseeds`, `-printusage`, dan `-printconfiguration` dalam konfigurasi R8 anda (atau jalankan `./gradlew :app:analyzeReleaseR8Config` dalam AGP 9.3+) dan bina APK keluaran anda. Sahkan bahawa kelas dan pembina SDK sasaran anda muncul dalam `seeds.txt` dan tidak muncul dalam `usage.txt`. Seterusnya, jalankan `apkanalyzer dex packages app-release.apk` **tanpa** `--proguard-mappings` dan semak silang `mapping.txt` untuk mengesahkan simbol DEX yang dikompilasi mentah mengekalkan nama asal yang tidak dikelirukan dan tandatangan kaedah mereka, kemudian jalankan `apkanalyzer` kali kedua dengan `--proguard-mappings`, `--proguard-seeds`, dan `--proguard-usages` untuk mengaudit bendera keadaan pengekalan (`k`, `x`, `r`, `d`).
Mengapa statistik pakej saluran Android berhenti berfungsi selepas pengerasan APK atau pemprosesan pos?
Apabila anda mengeksport pakej saluran Android daripada konsol atribusi, metadata pengenalan saluran dibenamkan ke dalam APK yang dieksport. Jika anda kemudian menjalankan alat pengukuhan, pembungkusan, atau penandatanganan semula APK pihak ketiga pada APK saluran yang dieksport itu, langkah pemprosesan pos boleh membatalkan tandatangan kriptografi APK atau menimpa metadata saluran vendor. Sentiasa lengkapkan pengecilan R8, pengerasan, `zipalign`, dan penandatanganan pada APK asas anda *sebelum* memuat naiknya ke konsol, dan sahkan APK saluran yang dieksport dengan `apksigner verify --verbose`.

Ringkasan dan Senarai Semak Pengesahan Binaan Keluaran

Memahami cara mengecualikan SDK mudah alih daripada obfuscation Android ProGuard dan R8 adalah penting untuk menghalang regresi atribusi senyap apabila beralih daripada ujian debug kepada binaan keluaran pengeluaran. Dengan mengesahkan peraturan pengguna yang digabungkan, menulis arahan -keep yang disasarkan secara sempit yang sepadan dengan laluan kelas sensitif huruf besar-kecil yang tepat di dalam arkib SDK anda, menghormati urutan binaan pra-muat naik untuk pakej saluran Android, dan menyemak silang fail output diagnostik R8 terhadap kod bait DEX mentah, jurutera Android boleh mengekalkan pengecilan kod penuh tanpa merosakkan deep linking tertunda atau pemulihan parameter.

Sebelum menerbitkan binaan keluaran Android yang diminimumkan ke Google Play atau mengeksport pakej saluran, laksanakan senarai semak pengesahan empat langkah ini:

  • Periksa Arkib SDK dan Konfigurasi Digabungkan: Periksa arkib SDK anda yang dimuat turun (seperti v2.1.0) dengan jar tf atau unzip -l untuk memeriksa laluan kelas yang tepat dan peraturan pengguna yang digabungkan, serta jalankan ./gradlew :app:analyzeReleaseR8Config (dalam AGP 9.3+) atau semak configuration.txt.

  • Semak Silang Laporan R8 dan Pengecam DEX Mentah: Sahkan bahawa titik masuk SDK yang diperlukan, pembina <init>() reflektif, medan model OpoData, kaedah ResultCallBack, dan tandatangan JNI muncul dalam seeds.txt, tiada dalam usage.txt, dan mengekalkan nama asal mereka dalam output apkanalyzer dex packages mentah (dijalankan tanpa --proguard-mappings) dan mapping.txt.

  • Kuatkuasakan Pengecilan Pra-Muat Naik dan Sahkan Tandatangan APK Saluran: Lengkapkan semua pengecilan R8, sebarang pengerasan pihak ketiga, zipalign (zipalign -c -P 16 -v 4), dan penandatanganan APK pada APK asas sebelum memuat naiknya untuk mengeksport pakej saluran Android, dan jalankan apksigner verify --verbose pada pakej yang dieksport.

  • Laksanakan Ujian Asap Keluaran Peranti Fizikal: Pasang APK keluaran yang ditandatangani dan diminimumkan pada peranti Android sebenar dan sahkan kedua-dua pemasangan parameter H5 (getInstallParam) dan kebangkitan satu klik (handleDeepLink).

Pasukan kejuruteraan boleh mendaftarkan aplikasi dan memuat naik APK asas mereka yang dikelirukan pada konsol pembangun Openinstall untuk menguji eksport pakej saluran dan mengesahkan pemulihan parameter binaan keluaran.

Bahan Berkaitan

Share this article