จำนวนวิธีการอ้างอิงที่เพิ่มขึ้นหลังจากการทำให้เป็นโมดูลแอ


16

ณ : 3.5.3; ปลั๊กอิน Gradle Android: 3.5.0; Gradle: 5.6.2;

เราสังเกตเห็นการเพิ่มขึ้นอย่างมากของจำนวนวิธีการที่อ้างอิงในแอปของเราหลังจากแยกโมดูล 'แอป' เป็นโมดูลขนาดเล็กหลาย ๆ ตัว แต่สิ่งที่แปลกคือการเพิ่มวิธีการอ้างอิงโดยแต่ละชั้นเรียนจะน้อยกว่าผลรวมที่กล่าวถึงใน Android Apk Analyzer Tool

เพื่อจุดประสงค์ในการทดสอบฉันได้ย้าย WebActivity.class จากโมดูล 'แอป' เป็นโมดูล 'อะแดปเตอร์' และจำนวนวิธีการอ้างอิงเพิ่มขึ้น 181 วิธี

เพื่อสรุป:

app / WebActivity = 63546วิธีการอ้างอิงจริง แต่แสดงวิธี65394 adapter / WebActivity = 63543วิธีการอ้างอิงจริง แต่แสดง65575วิธี

เราสังเกตว่า 'จำนวนวิธีอ้างอิงที่อ้างอิง' เพิ่มขึ้นเกือบ 10k หลังจากเพิ่ม / แยก 4 โมดูลใหม่

ปัญหาที่แน่นอนคืออะไร?

การทำให้เป็นโมดูลของแอพสามารถเพิ่มวิธีอ้างอิงได้อย่างไรนับได้สูงมาก

ต่อไปนี้เป็นภาพหน้าจอที่ฉันถ่ายด้วยความแตกต่างเพียงอย่างเดียวของ APKs สองอย่างคือ WebActivity ย้ายจากโมดูล 'แอป' เป็น 'อะแดปเตอร์' โมดูลและ 181 วิธีการอ้างอิงที่เพิ่มขึ้น:

WebActivity ในโมดูล 'แอป' ป้อนคำอธิบายรูปภาพที่นี่

ย้าย WebActivity ไปที่โมดูล 'adapter' ป้อนคำอธิบายรูปภาพที่นี่

ในภาพหน้าจอทำไมการเพิ่มวิธีการอ้างอิงโดยแต่ละคลาส (ทำเครื่องหมายด้วยสีแดง) ไม่เท่ากับผลรวมที่กำหนดใน Apk Analyzer?


ฉันได้สร้างปัญหาแล้วคุณสามารถติดตามได้ที่นี่issuetracker.google.com/issues/146957168
Rohit Surwase

คำตอบ:


9

ฉันอ่านเกี่ยวกับประสิทธิภาพของโค้ดและพารามิเตอร์การปรับตั้งมาเป็นเวลานานแล้วโปรแกรม Android เป็นหนึ่งในสิ่งที่ฉันสนใจ

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

ตามที่ผู้พัฒนา Android ได้ระบุไว้

โมดูลสามารถสร้างทดสอบและดีบักได้อย่างอิสระ

ดังนั้นโมดูลมีของตัวเองGradle และพึ่งพา .and Hierarchy Viewerคุณสามารถสำรวจในโครงการ

ตามความเป็นจริงModularizationเน้นเรื่องการบำรุงรักษา ซึ่งแตกต่างจากเรื่องประสิทธิภาพเนื่องจาก Modularization มีผลกระทบที่สำคัญนี้:

  • เพิ่มความลึกของการสืบทอด

นี่คือแผนภาพที่ฉันวางแผนลงเพื่อให้ชัดเจน อย่างที่คุณเห็นในขณะที่ใช้โมดูลแยกเพื่อเรียกใช้เมธอด A 2N micro secsเปรียบเทียบกับN micro secsโดยไม่ใช้โมดูลแยก

ป้อนคำอธิบายรูปภาพที่นี่

คำถามนี้อยู่ในใจของคุณว่าวิธีการอ้างอิงนับสิ่งที่เกี่ยวข้องกับความลึกของการสืบทอด?

คำตอบคือ:แม้ว่าการใช้ modularization เพิ่มอ้างอิง Methods.but มันไม่จริงส่งผลกระทบต่อประสิทธิภาพการทำงานของแอพพลิและปัญหาที่เป็นไปได้ที่สำคัญคือความลึกของมรดกซึ่งในกรณีส่วนใหญ่เป็นเพิกเฉยได้

ฉันเน้นว่าวิธีการอ้างอิงที่เพิ่มขึ้นในการทำให้เป็นโมดูลนั้นเป็นเพราะแต่ละโมดูล Gradle & Dependencies

การทำให้เป็นโมดูลของแอพสามารถเพิ่มวิธีอ้างอิงได้อย่างไรนับได้สูงมาก

เงื่อนไขที่เครื่องมือวิเคราะห์ APK ส่งผลกระทบสำคัญอ้างอิง

นอกจากนี้โปรดทราบว่าการย่อขนาดและการย่อขนาดแต่ละรายการสามารถเปลี่ยนแปลงเนื้อหาของไฟล์ DEX ได้อย่างมากหลังจากรวบรวมซอร์สโค้ด

นอกเหนือจากแถลงการณ์อย่างเป็นทางการข้างต้นแล้วฉันต้องการเพิ่มเงื่อนไขอื่นที่ตัววิเคราะห์ APK ที่มีผลกระทบ:

นักพัฒนามีประสบการณ์เท่าไหร่ในการทำให้เป็นโมดูล?

การทำให้เป็นโมดูลเป็นเหมือนบ้านที่สถาปัตยกรรม (ผู้พัฒนา)กำหนดว่าควรจะเป็นห้องครัวและสถานที่ที่ควรจะเป็นห้องน้ำและที่ควรเป็นห้องสุขา ถ้าสถาปัตยกรรมตัดสินใจรวมห้องสุขาและห้องครัวเข้าด้วยกัน ใช่นี่เป็นหายนะ

สิ่งนี้อาจเกิดขึ้นในขณะที่การทำให้เป็นโมดูลถ้านักพัฒนาไม่มีประสบการณ์มากนัก


ตอบคำถาม OP เพิ่มเติมจากข้อมูลเพิ่มเติม

ที่นี่ฉันจะตอบคำถามที่พบบ่อย op ในความคิดเห็น

เพราะเหตุใด Gradle ที่แยกต่างหากจึงรวมเข้ากับวิธีการอ้างอิงจึงถูกนับ? และสำหรับการอ้างอิงแยกต่างหากหากผลลัพธ์สุดท้ายเป็น APK เดียวฉันไม่คิดว่าการอ้างอิงซ้ำใน 'แอป' และโมดูลคุณลักษณะจะเพิ่มเข้าไปในการนับวิธีที่อ้างอิง

เนื่องจากสามารถสร้างโมดูลทดสอบและดีบั๊กได้ดังนั้นพวกเขาจึงต้องมี Gradle & Dependencies ของตัวเอง

ในขณะที่กำลังปฏิบัติตามโครงการหลายโมดูลคอมไพเลอร์จะสร้าง.dexไฟล์หลายไฟล์ซึ่งรวมถึง:

  • .dexไฟล์สำหรับการอ้างอิงรวมแบบบูรณาการ
  • โมดูล.dexs

.dexไฟล์การพึ่งพาคือการรวมกันของโมดูล gradles ทั้งหมด

เรามาดูกันว่าโมดูล gradle มีผลกระทบอย่างไรกับ Mothods Count สุดท้าย!

มี2 APKวินาทีที่มีผลลัพธ์เหมือนกัน แต่มีความแตกต่างในวิธีการอ้างอิง

รูปที่ 1 รูปที่ 2

พวกเขาทั้งสองกิจกรรมที่ว่างเปล่าที่มี1.7kความแตกต่างในวิธีการอ้างอิงนับที่สูงมากขึ้นอยู่กับการทำงานของพวกเขา พวกเขาแตกต่างที่สำคัญคือในการไล่ระดับสีของโมดูลของพวกเขาหนึ่งในนั้นได้รับการกำหนดค่าให้

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}

อีกอันกำหนดค่าให้

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.2.0-alpha01'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
}

แม้ว่าพวกเขาจะเป็นเพียงกิจกรรมที่ว่างเปล่า แต่ความแตกต่างเล็กน้อยที่สุดใน Gradle ทำให้เกิด1.7kความแตกต่างในวิธีการอ้างอิง

และApp Gradle คือ

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation project(path: ':module')
}

ข้อกังวลหลักคือสาเหตุที่การเพิ่มจำนวนวิธีอ้างอิงแต่ละรายการแตกต่างจากวิธีการอ้างอิงทั้งหมดใน Apk Analyzer

นี่เป็นเพียงตัวกรอง IDE ไม่มีอะไรอื่น แน่นอนถ้าคุณเลือก.dexไฟล์ที่อ้างอิงวิธีการนับจะเท่ากับ SUM ของแต่ละแถววิธีการอ้างอิงที่นับ แต่ถ้าคุณเลือกหลาย.dexไฟล์คุณจะเห็นความแตกต่างใน SUM และนับจริงเพราะความเท่าเทียมกันในการอ้างอิงที่ต้องการ กรองพวกเขา

ในภาพหน้าจอของคุณคุณได้เลือกหลาย.dexไฟล์จากนั้นตัววิเคราะห์ความเท่าเทียมกันของตัวกรอง

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

ในทางทฤษฎีมันไม่ควรเพิ่มจำนวนวิธีการอ้างอิง แต่ดังที่ฉันอธิบายไว้ประสบการณ์นักพัฒนาจะส่งผลกระทบอย่างมากต่อผลลัพธ์สุดท้าย

Team Analyzerควรตรวจสอบและแก้ไขปัญหาด้านประสิทธิภาพก่อนที่จะวางจำหน่าย

  • กฎ proguard
  • หดและทรัพยากร minified
  • AndroidManifest.xml
  • การตั้งค่าการไล่ระดับสี

ตอนนี้ฉันต้องการชี้แจงว่าประสบการณ์นักพัฒนาซอฟต์แวร์และการบำรุงรักษารหัสมีผลต่อผลลัพธ์สุดท้ายอย่างไร ทุกครั้งที่ APK ของคุณใช้การอ้างอิงจากศูนย์กลาง

รูปที่ 3

ในตัวอย่างข้างต้น I'v เพิ่มขึ้น5.1kในวิธีการอ้างอิงนับแม้ว่าฉันมีศูนย์กลางการพึ่งพา !!!!!

เป็นไปได้อย่างไร

คำตอบคือ:ฉันเพิ่งเพิ่ม.jarไฟล์ที่ไม่มีประโยชน์และซ่อนอยู่ในlibsไดเรกทอรีของโครงการ ง่ายเหมือนที่คุณเห็นฉันได้รับผลสุดท้าย

ที่คุณสามารถดูประสบการณ์ผู้พัฒนาส่งผลกระทบต่อ result.as สุดท้ายผลให้จวนเป็นไปได้ว่านับวิธีการอ้างอิงที่จะเพิ่มขึ้นถึงแม้ว่าในทางทฤษฎีควรไม่

และทำไมไม่มีความแตกต่างในวิธีการอ้างอิงเมื่อฉันรวบรวมเฉพาะโมดูล 'แอพ' โดยการปิดการคอมไพล์แบบขนาน? มันควรจะลดลงเพราะมีเพียงการใช้งานโมดูลของการพึ่งพาเท่านั้นใช่ไหม?

การรวบรวมไม่มีความสัมพันธ์ใด ๆ กับวิธีการอ้างอิงนับว่าเป็นไปตามสิ่งที่นักพัฒนาต้องการที่จะปฏิบัติตาม


ข้อสรุป

ฉันได้ครอบคลุมความเป็นไปได้ทั้งหมดเกี่ยวกับปัญหานี้แล้ว แน่นอนมันสามารถเกิดขึ้นได้จากสถานการณ์ที่แตกต่างและนักพัฒนาโดยใช้แนวทางนี้สามารถแก้ไขปัญหาได้

  • ฉันหวังว่าคุณจะพบว่าทำไมวิธีการอ้างอิงถึงเพิ่มขึ้นและทำไมในบางกรณีมันอาจเพิ่มขึ้นอย่างมาก
  • โมดูลมี Gradle & Dependencies และโมดูลการเพิ่มโมดูล ดังนั้นวิธีการอ้างอิงเหล่านี้
  • การทำให้เป็นโมดูลนั้นส่งผลกระทบต่อประสิทธิภาพการทำงานของแอพที่ไม่อาจเพิกเฉยได้ แต่ทำให้การบำรุงรักษาแอปของคุณดีขึ้นมาก
  • ประสบการณ์ของนักพัฒนาในการทำให้เป็นโมดูลยังส่งผลต่อผลลัพธ์สุดท้ายอย่างมาก

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



ขอบคุณ Mr.AF ฉันหวังว่าจะได้รับคำตอบหลังจาก "คำถามนี้มาถึงใจของคุณว่าวิธีการอ้างอิงนับสิ่งที่เกี่ยวข้องกับความลึกของการสืบทอดหรือไม่คำตอบคือ" แต่คุณไม่ได้ตอบว่า คุณช่วยอธิบายรายละเอียดเกี่ยวกับสาเหตุที่ความลึกของการถ่ายทอดเพิ่มจำนวนวิธีอ้างอิงที่อ้างอิงได้ไหม ในกรณีของเราเราไม่ได้เพิ่มเลเยอร์พิเศษใด ๆ แต่เพียงแยกโมดูล 'แอป' มีโอกาสที่จะเพิ่มจำนวนวิธีอ้างอิงในกรณีที่โมดูลคุณลักษณะเข้าถึงวิธีการของโมดูลคุณสมบัติอื่นผ่านโมดูล 'แอป' นี่คือเหตุผลหรือไม่
Rohit Surwase

@RohitSurwase คำตอบคือคำสั่งที่เหลือความลึกของการสืบทอดไม่เพิ่มการอ้างอิงเมธอดการทำให้เป็นโมดูลและการทำให้เป็นโมดูลและความลึกของการสืบทอด
Mr.AF

@RohitSurwase ฟีเจอร์ที่เข้าถึงฟีเจอร์อื่นในโมดูลอื่นจริง ๆ แล้วจะไม่เพิ่มวิธีการอ้างอิงที่นับได้มาก เหตุผลหลักในการเพิ่มจำนวนการอ้างอิงวิธีการคือ Gradle & Dependencies ที่แต่ละโมดูลต้องการ
Mr.AF

@RohitSurwase คุณชี้เคล็ดลับที่ดีเกี่ยวกับโมดูลกับโมดูลที่เกี่ยวข้อง ตามความเป็นจริงถ้า 2 โมดูลมีความสัมพันธ์มากเกินไปและวิธีการอ้างอิงแล้วพวกเขาควรจะรวมกันเพื่อประสิทธิภาพที่ดีขึ้น จริง ๆ แล้วโมดูลจะต้องมีความเป็นอิสระในระยะ & แนวคิด
Mr.AF

1
@RohitSurwase ในขณะที่ฉัน saied jar ที่ไม่ได้ใช้อาจไม่ใช่กรณีของคุณบางสิ่งที่ฉันหมายถึงเป็นประสบการณ์ของนักพัฒนาซอฟต์แวร์ และฉันแสดงรายการแหล่งข้อมูลที่เป็นไปได้ทั้งหมดที่คุณต้องการค้นหา
Mr.AF

2

ตอบคำถามของฉันเองในฐานะที่เป็นวิธีการแก้ปัญหาที่เพิ่งคลิกในใจของฉันแม้ว่าจะไม่พยายาม แต่จะทำงานได้อย่างแน่นอนหรืออาจเป็นไปได้มากที่สุด :) คำตอบของ Mr.AFนั้นเป็นประโยชน์อย่างมากในการหาทางออกสุดท้าย มันพูดถึงทำไม? แต่ไม่ใช่วิธีหลีกเลี่ยงหรือปรับปรุงให้ดีขึ้น

นี่คือวิธีในการเรียกคืนจำนวนวิธีอ้างอิงเดิม / จริง -

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

ดังนั้นหากเวลาในการสร้างไม่ใช่ความกังวลของคุณ แต่การนับวิธีการอ้างอิงนั้นคุณสามารถวาดแผนผังการพึ่งพาของโมดูลทั้งหมดและหลีกเลี่ยงการเพิ่มการพึ่งพาซ้ำโดยใช้ 'api' ในโมดูลฐาน วิธีนี้แม้แต่โมดูลระดับสูงก็สามารถใช้การพึ่งพาที่เพิ่มโดยโมดูลฐานซึ่งจะหลีกเลี่ยงการซ้ำซ้อน จำไว้ว่านี่จะเพิ่มเวลาสร้าง

เราสามารถทำได้ทั้งสองอย่างถ้าเราสามารถแยกความแตกต่างของการขึ้นต่อกันสำหรับการดีบักและปล่อยบิลด์ เพิ่มการอ้างอิงทั้งหมดที่ใช้'การใช้งานสำหรับการแก้ปัญหาการสร้างและเพิ่มที่จำเป็นเท่านั้นและเพิ่มประสิทธิภาพการอ้างอิงสำหรับการเปิดตัวสร้างโดยใช้ 'API' การดีบักบิลด์ด้วยวิธีนี้จะเร็วขึ้นและการปล่อยบิลด์จะช้าลงซึ่งมีราคาไม่แพง

หมายเหตุ: ฉันจะอัปเดตคำตอบนี้เมื่อฉันหาวิธีการให้การอ้างอิงแยกต่างหากสำหรับการตรวจแก้จุดบกพร่องและการสร้างรุ่น


ฉันชอบมันวัสดุที่ดี
Mr.AF

0

ฉันเห็นความแตกต่างทั้งหมดในแพ็คเกจ 'com' ของคุณ คุณสามารถขยายและเปรียบเทียบคลาสที่แน่นอนที่ถูกลดขนาดได้ หากคุณสร้างด้วย R8 ล่าสุดจะสามารถลบรหัสบางส่วนได้ตามค่าเริ่มต้น เมื่อคุณใส่บางคลาสลงในโมดูลตัวย่อไม่ทราบว่าสามารถลบคลาสหรือวิธีสาธารณะหรือต้องอยู่ในโมดูลอื่นต่อไป ป้อนคำอธิบายรูปภาพที่นี่


ใช่ฉันขยายและตรวจสอบแต่ละแพ็คเกจรวมถึง 'com' ข้อกังวลหลักคือทำไมการเพิ่มจำนวนวิธีอ้างอิงแต่ละรายการจึงแตกต่างจากวิธีอ้างอิงทั้งหมดใน Apk Analyzer
Rohit Surwase
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.