จะเก็บ / แยกเส้นทางแพ็กเกจเฉพาะเมื่อใช้ proguard ได้อย่างไร?


110

ฉันต้องการแยกเส้นทางไฟล์บางส่วนจาก ProGuard ตัวอย่างcom.myapp.customcomponents

ฉันจะทำเช่นนี้ได้อย่างไร? ฉันเกลียดที่จะวางแฟล็ก -keep สำหรับไฟล์คอมโพเนนต์ที่กำหนดเองทุกไฟล์ที่ฉันมีในไดเร็กทอรีนี้

ฉันได้ลองทำสิ่งต่อไปนี้แล้ว แต่ไม่ได้ผล:

-keep public class com.myapp.customcomponents.*

คำตอบ:


242

คุณไม่ได้ระบุว่ามันไม่ได้ผลในทางใด การกำหนดค่าของคุณเก็บชื่อของคลาสสาธารณะทั้งหมดไว้ในแพ็คเกจที่ระบุ:

-keep public class com.myapp.customcomponents.*

คอนฟิกูเรชันต่อไปนี้เก็บชื่อคลาสพับลิกทั้งหมดไว้ในแพ็กเกจที่ระบุและแพ็กเกจย่อย:

-keep public class com.myapp.customcomponents.**

คอนฟิกูเรชันต่อไปนี้เก็บชื่อของคลาส / ฟิลด์ / เมธอดสาธารณะ / ที่มีการป้องกันทั้งหมดไว้ในแพ็กเกจที่ระบุและแพ็กเกจย่อย:

-keep public class com.myapp.customcomponents.** {
  public protected *;
}

8
เครื่องหมายดอกจันคู่ (**) ไม่รวบรวมอีกต่อไป (Android Studio 4.0)
Daniel

2
Android Studio 4.x จะแสดงข้อผิดพลาดเช่น "Unresolved class name" เป็นต้นสำหรับเครื่องหมายดอกจันคู่ (**) แต่จะทำงานได้ตามที่คาดไว้
Mahmudul Hasan Shohag

ได้รับการแก้ไขและจะไม่ให้ข้อผิดพลาดในการเผยแพร่ที่กำลังจะมาโปรดตรวจสอบรายละเอียดที่นี่
Shadygoneinsane

56

เพิ่มบรรทัดต่อไปนี้ที่ด้านล่างของการกำหนดค่า ProGuard ของคุณ:

-keep class com.facebook.** { *; }

แทนที่ชื่อแพ็คเกจตามนี้แพ็คเกจcom.facebookจะถูกแยกออกจาก ProGuard


13
ทำไมต้องเก็บและไม่ใช้ร่วมกัน
Jongz Puangput

@ Jongz Puangput ถ้าฉันถูก - ถ้าแอพไม่ใช้แพ็คเกจ com.facebook จากนั้นในบิลด์จะแสดงหมายเหตุ "การกำหนดค่าหมายถึงคลาสที่ไม่รู้จัก ... " -dontwarn ปิดการใช้งานบันทึกนี้
Yura Shinkarev

14
สิ่งที่ไม่{ *; }หมายถึง?
มูฮัมหมัดบาบาร์

15
@MuhammadBabar ฉันหมายถึงสมาชิกทุกคนวิธีการคลาสในทุกขอบเขตในระยะสั้นทุกอย่าง!
Omar El Don

1

ผู้คนจำนวนมากดูเหมือนจะแนะนำให้-keep class com.myapp.customcomponents.** { *; }เป็นวิธียกเว้นเส้นทางจากการประมวลผล ดูที่นี่:

  1. ไม่รวมแพ็คเกจจาก proguard
  2. ทำให้ Proguard ละเว้นแพ็คเกจโดยสิ้นเชิง
  3. ป้องกันไม่ให้ไดเร็กทอรีจากการสับสนของ proguard

ปัญหาในการแก้ปัญหานี้คือยังคงมีความสับสนบางอย่างเกิดขึ้นซึ่งสามารถทำลายรหัสของคุณได้ คุณสามารถดูการทำแผนที่ในการพิมพ์แผนที่:

java.lang.String toString() -> toString
int getMemoizedSerializedSize() -> getMemoizedSerializedSize
void setMemoizedSerializedSize(int) -> setMemoizedSerializedSize
int getSerializedSize() -> getSerializedSize
boolean equals(java.lang.Object) -> equals
int hashCode() -> hashCode

วิธีแก้ปัญหาที่ฉันเลือกใช้คือกระบวนการสองขั้นตอน ขั้นแรกให้ใช้injarsกับตัวกรองเพื่อเลือกเส้นทางแพ็กเกจที่ฉันต้องการดำเนินการ เป็นไปได้ที่จะเพิ่มแพทเกจอื่น ๆ เป็นไลบรารี

-injars       artifacts/in.jar(org/toprocess/**.class)
-outjars      out/processed.jar
-libraryjars  artifacts/in.jar(org/skipped/**.class)
-libraryjars  artifacts/in.jar(org/moreskipped/**.class)

ประการที่สองผสานโถที่ผ่านการประมวลผลกับโถดั้งเดิม แต่มีเพียงเส้นทางที่ข้ามไป

-injars  out/processed.jar
-injars  artifacts/in.jar(org/skipped/**.class)
-injars  artifacts/in.jar(org/moreskipped/**.class)
-outjars out/merged.jar

-dontshrink
-dontoptimize
-dontobfuscate

ผลลัพธ์คือ jar ที่ผสานซึ่งเป็นการรวมกันของพา ธ แพ็กเกจที่ประมวลผลและพา ธ ที่ข้าม แบบฝึกหัดนี้ไม่ถูกต้องหากมีใครสามารถให้วิธีข้ามการประมวลผลของเส้นทางบางอย่างได้โดยสิ้นเชิง (ซึ่งฉันไม่พบ)


1

สิ่งที่ใช้ได้ผลสำหรับฉันโดยใช้ Android Studio 4.0 คือ:

-keepclassmembers class com.myapp.customcomponents.* {
    <fields>;
    <init>();
    <methods>;
}

ดอกจันคู่ (**) ในคำตอบอื่นไม่ได้ผลสำหรับฉัน ฉันลองใช้การกำหนดค่าข้างต้นกับ R8 แล้วใช้งานได้ดี


คำตอบนี้เป็นคำตอบที่ทันสมัยที่สุดที่ฉันคิด ขอบคุณ.
Gogo-the-Cat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.