การติดตั้งแอพ Android ทำงานอย่างไรภายใต้ประทุน

A smartphone on engineering blueprints with gears, illustrating how app installation works

เมื่อคุณแตะ "ติดตั้ง" ในไฟล์ APK หรือดาวน์โหลดแอปจาก Play Store ลำดับการดำเนินการที่ซับซ้อนจะเริ่มต้นขึ้นในเบื้องหลัง สิ่งที่ดูเหมือนจะเป็นแถบความคืบหน้าที่เรียบง่ายจริงๆ แล้วแสดงถึงขั้นตอนต่างๆ มากมายที่เกี่ยวข้องกับการแยกวิเคราะห์แพ็คเกจ การตรวจสอบการเข้ารหัส การจัดการสิทธิ์ การแตกไฟล์ และการเพิ่มประสิทธิภาพโค้ด การทำความเข้าใจกระบวนการนี้จะช่วยอธิบายว่าทำไมบางครั้งการติดตั้งจึงล้มเหลว และสิ่งที่คุณสามารถทำได้

ในบทความนี้ เราจะอธิบายทุกขั้นตอนสำคัญของขั้นตอนการติดตั้ง Android ตั้งแต่ช่วงเวลาที่ระบบได้รับ APK จนถึงจุดที่พร้อมเปิดตัวแอป

ขั้นตอนที่ 1: เริ่มต้นการติดตั้ง

กระบวนการติดตั้งเริ่มต้นแตกต่างกันไปขึ้นอยู่กับแหล่งที่มา:

  • เล่นสโตร์: แอป Play Store ดาวน์โหลด APK (หรือแยก APK) และเรียกตัวติดตั้งแพ็คเกจของระบบพร้อมสิทธิพิเศษที่เลี่ยงการยืนยันของผู้ใช้
  • ไซด์โหลด: เมื่อคุณเปิดไฟล์ APK Android จะเปิดตัวกิจกรรมการติดตั้งแพ็คเกจ บน Android 8.0 และใหม่กว่า แอปที่ติดตั้งจะต้องมีสิทธิ์ "ติดตั้งแอปที่ไม่รู้จัก" สำหรับแหล่งที่มาเฉพาะ
  • เอดีบี: คำสั่ง adb install สื่อสารโดยตรงกับบริการตัวจัดการแพ็คเกจผ่าน USB โดยไม่ผ่านตัวติดตั้งแบบกราฟิกทั้งหมด

โดยไม่คำนึงถึงแหล่งที่มา การติดตั้งทั้งหมดจะเข้าถึงบริการระบบเดียวกันในที่สุด: PackageManagerService (PMS) นี่คือหน่วยงานกลางสำหรับการดำเนินการแพ็คเกจทั้งหมดบน Android

ขั้นตอนที่ 2: การแยกวิเคราะห์แพ็คเกจ

ก่อนอื่น ระบบจำเป็นต้องทำความเข้าใจก่อนว่ากำลังติดตั้งอะไร PackageManagerService เรียกใช้ PackageParser เพื่ออ่านไฟล์ APK และแตกข้อมูลเมตาของมัน

โปรแกรมแยกวิเคราะห์จะอ่านไฟล์ AndroidManifest.xml จากภายใน APK ไฟล์ XML ไบนารีนี้มีข้อมูลสำคัญ:

  • ชื่อแพ็คเกจ: ตัวระบุเฉพาะสำหรับแอป (เช่น com.example.myapp)
  • รหัสเวอร์ชันและชื่อ: ใช้เพื่อพิจารณาว่านี่คือการอัพเกรดหรือการติดตั้งใหม่
  • เวอร์ชัน SDK ขั้นต่ำและเป้าหมาย: กำหนดความเข้ากันได้กับอุปกรณ์
  • สิทธิ์ที่ประกาศ: ทั้งสิทธิ์ที่แอปร้องขอและสิทธิ์ที่กำหนดเองที่กำหนด
  • กิจกรรม ส่วนประกอบ: บริการ เครื่องรับกระจายเสียง และผู้ให้บริการเนื้อหาที่แอปลงทะเบียน
  • ข้อกำหนดของ คุณสมบัติด้านฮาร์ดแวร์และซอฟต์แวร์: เช่น กล้อง, GPS หรือเวอร์ชัน OpenGL เฉพาะ

หากไฟล์ Manifest มีรูปแบบไม่ถูกต้องหรือโครงสร้าง APK ไม่ถูกต้อง การติดตั้งจะล้มเหลวในขั้นตอนนี้พร้อมกับข้อความ "ข้อผิดพลาดในการแยกวิเคราะห์" นี่เป็นหนึ่งในสาเหตุที่พบบ่อยที่สุดที่ทำให้ APK ที่ไซด์โหลดไม่สามารถติดตั้งได้

ขั้นตอนที่ 3: การตรวจสอบความเข้ากันได้

เมื่อแยกวิเคราะห์รายการแล้ว ระบบจะทำการตรวจสอบความเข้ากันได้หลายชุด:

  • เวอร์ชัน SDK: หาก minSdkVersion ของแอปสูงกว่าระดับ API ของอุปกรณ์ การติดตั้งจะถูกปฏิเสธ
  • ความเข้ากันได้ของ ABI: หาก APK มีไลบรารีดั้งเดิม ระบบจะตรวจสอบว่าตรงกับสถาปัตยกรรม CPU ของอุปกรณ์หรือไม่ APK ที่มีเฉพาะไลบรารี armeabi-v7a จะไม่ติดตั้งบนอุปกรณ์ที่ใช้ x86 เท่านั้น
  • คุณสมบัติที่จำเป็น: หากแอปประกาศคุณสมบัติฮาร์ดแวร์ที่จำเป็น (เช่น android.hardware.telephony) ระบบจะตรวจสอบว่าอุปกรณ์รองรับคุณสมบัติดังกล่าว
  • พื้นที่เก็บข้อมูลที่มีอยู่: ระบบจะตรวจสอบว่ามีพื้นที่ว่างเพียงพอที่จะติดตั้งแอปหรือไม่ รวมถึงพื้นที่สำหรับไลบรารีเนทิฟที่แตกออกมาและไฟล์ DEX ที่ปรับให้เหมาะสม

ขั้นตอนที่ 4: การตรวจสอบลายเซ็น

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

กระบวนการตรวจสอบขึ้นอยู่กับแผนการลงนามที่มีอยู่:

ลายเซ็น V1 (การลงนาม JAR)

ระบบจะตรวจสอบไดเร็กทอรี META-INF/ เพื่อหาไฟล์ลายเซ็น (.SF, .RSA หรือ .DSA แต่ละไฟล์ใน APK ได้รับการตรวจสอบเทียบกับไดเจสต์ที่แสดงอยู่ในไฟล์ Manifest สิ่งนี้ช้าเพราะทุกไฟล์จะต้องถูกแฮชแยกกัน)

ลายเซ็น V2 (โครงการลายเซ็น APK v2)

เปิดตัวใน Android 7.0 รูปแบบนี้ลงนาม APK ทั้งหมดเป็นไบนารี่หยด บล็อกลายเซ็นถูกแทรกระหว่างไดเร็กทอรีกลาง ZIP และเรกคอร์ดจุดสิ้นสุดของไดเร็กทอรีกลาง การยืนยันทำได้เร็วกว่ามากเนื่องจากทำงานบนไบต์ดิบโดยไม่จำเป็นต้องขยายขนาดแต่ละรายการ

ลายเซ็น V3 (การหมุนคีย์)

พร้อมใช้งานจาก Android 9.0, V3 ขยาย V2 พร้อมรองรับการหมุนเวียนคีย์ ประกอบด้วยโครงสร้างการพิสูจน์การหมุนเวียนที่เชื่อมโยงคีย์การเซ็นชื่อเก่าและใหม่ ช่วยให้นักพัฒนาสามารถเปลี่ยนคีย์การเซ็นชื่อของตนในขณะที่ยังคงความเข้ากันได้ของการอัปเดต

ลายเซ็น V4 (ส่วนเพิ่ม)

Android 11 เปิดตัว V4 สำหรับการติดตั้งเพิ่มเติม โดยมีลายเซ็นแบบต้นไม้ Merkle ที่ช่วยให้สามารถตรวจสอบแต่ละบล็อกในขณะที่สตรีมไปยังอุปกรณ์ได้

หากการตรวจสอบลายเซ็นล้มเหลวไม่ว่าด้วยเหตุผลใดก็ตาม การติดตั้งจะถูกยกเลิกทันที คุณสามารถตรวจสอบลายเซ็น APK ก่อนการติดตั้งได้โดยใช้ เครื่องมือตรวจสอบ APK ของเรา

อัปเดตการจับคู่ลายเซ็น

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

ขั้นตอนที่ 5: การยืนยันผู้ใช้

สำหรับการติดตั้งแบบไซด์โหลด ระบบจะแสดงกล่องโต้ตอบการยืนยันการติดตั้งที่แสดง:

  • ชื่อแอปและไอคอน (ดึงมาจากทรัพยากรของ APK)
  • สิทธิ์การร้องขอแอป (บน Android เวอร์ชันเก่า)
  • ไม่ว่าจะเป็นการติดตั้งใหม่หรือการอัปเดต
  • คำเตือนเกี่ยวกับแหล่งที่มาของแอปหรือความเสี่ยงที่อาจเกิดขึ้น

ใน Android 12 ขึ้นไป หน้าจอยืนยันจะง่ายกว่า เนื่องจากจะให้สิทธิ์รันไทม์แยกกันเมื่อแอปต้องการสิทธิ์ดังกล่าวในครั้งแรก แทนที่จะให้สิทธิ์ในเวลาติดตั้ง

ขั้นตอนที่ 6: การแยกไฟล์และการวางตำแหน่ง

เมื่อผู้ใช้ยืนยัน (หรือสำหรับการติดตั้ง Play Store โดยอัตโนมัติ) ระบบจะเริ่มแยกและวางไฟล์:

ที่เก็บข้อมูลAPK

ไฟล์ APK เองก็ถูกคัดลอกไปยัง /data/app/[package-name]-[random]/base.apk สำหรับการติดตั้ง APK แบบแยก ไฟล์เพิ่มเติม เช่น split_config.arm64_v8a.apk จะถูกวางไว้ข้างๆ APK พื้นฐาน APK ดั้งเดิมในโฟลเดอร์ดาวน์โหลดไม่ได้รับการแก้ไขหรือลบ

การแยกไลบรารีพื้นเมือง

หาก APK มีไลบรารีดั้งเดิม (ในไดเร็กทอรี lib/ ไลบรารีเหล่านั้นจะถูกแตกออกมาเป็น /data/app/[package-name]-[random]/lib/[abi]/ ใน Android เวอร์ชันใหม่กว่า แอปสามารถเลือกที่จะบีบอัดไลบรารีดั้งเดิมภายใน APK และโหลดไลบรารีโดยตรงโดยใช้ android:extractNativeLibs="false" ซึ่งช่วยประหยัดพื้นที่จัดเก็บข้อมูล)

การสร้างไดเร็กทอรีข้อมูล

ระบบจะสร้างไดเร็กทอรีข้อมูลส่วนตัวของแอปที่ /data/data/[package-name]/ (หรือ /data/user/0/[package-name]/ บนอุปกรณ์ที่มีผู้ใช้หลายคน) ไดเร็กทอรีนี้เป็นของ Linux UID ที่ไม่ซ้ำกันซึ่งกำหนดให้กับแอป ทำให้มั่นใจได้ว่าไม่มีแอปอื่นใดที่สามารถเข้าถึงได้หากไม่มีสิทธิ์รูท

ขั้นตอนที่ 7: การเพิ่มประสิทธิภาพ DEX

ขั้นตอนนี้เป็นขั้นตอนที่ Android แปลงรหัสไบต์ของแอปเป็นรูปแบบที่ปรับให้เหมาะกับฮาร์ดแวร์เฉพาะของอุปกรณ์ กระบวนการนี้มีการพัฒนาอย่างมากเหนือประวัติศาสตร์ของ Android:

ยุค Dalvik (Android 4.4 และรุ่นก่อนหน้า)

เครื่องเสมือน Dalvik ดั้งเดิมใช้การคอมไพล์ Just-In-Time (JIT) ระหว่างการติดตั้ง ไฟล์ classes.dex ได้รับการปรับให้เป็นไฟล์ ODEX ที่มีไบต์โค้ดที่ได้รับการตรวจสอบและปรับให้เหมาะสมแล้ว สิ่งนี้ค่อนข้างเร็ว แต่หมายความว่าแอปทำงานช้าลงในช่วงรันไทม์เนื่องจากโค้ดส่วนใหญ่ยังคงถูกตีความ

ART กับ AOT (Android 5.0 ถึง 6.0)

Android Runtime (ART) เข้ามาแทนที่ Dalvik และแนะนำการคอมไพล์ Ahead-Of-Time (AOT) ระหว่างการติดตั้ง รหัสไบต์ DEX ทั้งหมดจะถูกคอมไพล์เป็นรหัสเครื่องเนทิฟ ทำให้แอปทำงานเร็วขึ้น แต่เพิ่มเวลาการติดตั้งและการใช้พื้นที่เก็บข้อมูลมากขึ้นอย่างมาก แอพบางตัวใช้เวลาติดตั้งหลายนาที

การรวบรวมโปรไฟล์ที่แนะนำ (Android 7.0+)

Modern Android ใช้วิธีการแบบไฮบริด ระหว่างการติดตั้ง จะมีการรวบรวมเฉพาะเส้นทางการเริ่มต้นที่สำคัญเท่านั้น ในขณะที่ผู้ใช้รันแอป ระบบจะรวบรวมโปรไฟล์การดำเนินการที่ระบุเส้นทางโค้ดที่ใช้บ่อย ในระหว่างการบำรุงรักษาที่ไม่ได้ใช้งาน (โดยทั่วไปคือขณะชาร์จข้ามคืน) ระบบจะรวบรวมเส้นทางลัดเหล่านี้ไปเป็นโค้ดเนทีฟ สิ่งนี้จะรักษาสมดุลของความเร็วการติดตั้ง การใช้พื้นที่เก็บข้อมูล และประสิทธิภาพรันไทม์

โค้ดที่คอมไพล์แล้วจะถูกจัดเก็บไว้ใน /data/dalvik-cache/ หรือข้าง APK เป็นไฟล์ .odex, .vdex และ .art ไฟล์ .vdex มีรหัส DEX ที่ตรวจสอบแล้ว ไฟล์ .odex มีโค้ดเนทิฟที่คอมไพล์แล้ว และไฟล์ .art มีอิมเมจฮีปที่เตรียมใช้งานไว้ล่วงหน้าเพื่อการเริ่มต้นที่เร็วขึ้น

ขั้นตอนที่ 8: การลงทะเบียนการอนุญาต

PackageManagerService ลงทะเบียนสิทธิ์และส่วนประกอบที่ประกาศของแอปกับระบบ:

  • สิทธิ์เวลาติดตั้ง (เช่น INTERNET หรือ VIBRATE จะได้รับโดยอัตโนมัติโดยไม่ต้องโต้ตอบกับผู้ใช้)
  • สิทธิ์รันไทม์ (เช่น CAMERA หรือ LOCATION ได้รับการลงทะเบียนแล้วแต่ไม่ได้รับอนุญาต แอปจะต้องขอเมื่อรันไทม์)
  • ตัวกรองเจตนา ได้รับการลงทะเบียนแล้ว ดังนั้นระบบจึงรู้ว่าแอปใดสามารถจัดการการกระทำใดได้ (เช่น การเปิด URL หรือการแชร์เนื้อหา)
  • ผู้ให้บริการเนื้อหา ได้รับการลงทะเบียนกับหน่วยงานเพื่อให้แอปอื่นสามารถสืบค้นได้

ขั้นตอนที่ 9: การรวมระบบ

ขั้นตอนสุดท้ายรวมแอปเข้ากับระบบ Android:

  • อัพเดตฐานข้อมูลแพ็คเกจ: ฐานข้อมูลแพ็กเกจของระบบ (/data/system/packages.xml) ได้รับการอัปเดตด้วยข้อมูลของแอปใหม่ รวมถึง UID ที่ได้รับมอบหมาย สิทธิ์ และการประกาศส่วนประกอบ
  • การแจ้งเตือนตัวเรียกใช้: ตัวเปิดหน้าจอหลักจะได้รับแจ้งเกี่ยวกับแอปใหม่ เพื่อให้สามารถแสดงไอคอนแอปได้
  • ออกอากาศ: ระบบส่งการออกอากาศ PACKAGE_ADDED เพื่อให้แอปอื่นๆ ตอบสนองต่อการติดตั้งใหม่ (เช่น แอปสำรองข้อมูลอาจกำหนดเวลาการสำรองข้อมูล)
  • บริบทของ SELinux: ไฟล์ของแอปมีป้ายกำกับด้วยบริบทความปลอดภัยของ SELinux ที่เหมาะสม โดยอิงตามเวอร์ชัน SDK เป้าหมายและการอนุญาตที่ประกาศ

เหตุใดการติดตั้งจึงล้มเหลว

การทำความเข้าใจไปป์ไลน์การติดตั้งจะช่วยวินิจฉัยความล้มเหลวทั่วไป:

  • "ข้อผิดพลาดในการแยกวิเคราะห์": APK เสียหาย ไม่สมบูรณ์ หรือมีรายการที่มีรูปแบบไม่ถูกต้อง สิ่งนี้มักเกิดขึ้นกับการดาวน์โหลดที่ไม่สมบูรณ์หรือไฟล์ที่แปลงไม่ถูกต้อง
  • "ไม่ได้ติดตั้งแอป" (ลายเซ็นไม่ตรงกัน): คุณกำลังพยายามอัปเดตแอปด้วย APK ที่ลงนามโดยคีย์อื่น คุณต้องถอนการติดตั้งเวอร์ชันที่มีอยู่ก่อน
  • "พื้นที่เก็บข้อมูลไม่เพียงพอ": พื้นที่ไม่เพียงพอสำหรับ APK, ไลบรารีที่แตกออกมา และเอาต์พุตการเพิ่มประสิทธิภาพ DEX โดยทั่วไปพื้นที่ที่ต้องการคือ 2-3 เท่าของขนาด APK
  • "แพ็คเกจขัดแย้งกับแพ็คเกจที่มีอยู่": ชื่อแพ็คเกจเดียวกันแต่ลายเซ็นต่างกัน เป็นเรื่องปกติเมื่อสลับระหว่าง Play Store และเวอร์ชันไซด์โหลด
  • ดาวน์เกรดเวอร์ชันถูกบล็อก: ตามค่าเริ่มต้น Android จะป้องกันการติดตั้งเวอร์ชันเก่ากว่าเวอร์ชันที่ใหม่กว่า ADB สามารถแทนที่สิ่งนี้ด้วย adb install -d

แยกการติดตั้ง APK

เมื่อติดตั้ง APK แบบแยก (จาก App Bundle) กระบวนการจะแตกต่างออกไปเล็กน้อย ระบบใช้ การติดตั้งตามเซสชัน API:

  1. มีการสร้างเซสชันการติดตั้งใหม่
  2. APK แยกแต่ละรายการจะถูกเขียนลงในเซสชัน
  3. เซสชั่นถูกคอมมิต ทำให้เกิดไปป์ไลน์การยืนยันแบบสมบูรณ์
  4. การแยกทั้งหมดต้องมีชื่อแพ็กเกจ รหัสเวอร์ชัน และใบรับรองการลงนามที่ตรงกัน

นี่คือกลไกที่ใช้โดยโปรแกรมติดตั้ง XAPK และเครื่องมือเช่น การรวม APKS เป็น APK ของเราเพื่อจัดการการติดตั้งหลายไฟล์

การติดตั้งผ่าน ADB

เมื่อคุณใช้ adb install กระบวนการจะข้ามตัวติดตั้งแบบกราฟิก แต่เป็นไปตามไปป์ไลน์ภายในเดียวกัน ADB สื่อสารกับบริการตัวจัดการแพ็คเกจผ่านการเชื่อมต่อซ็อกเก็ต รองรับแฟล็กเพิ่มเติมที่ไม่สามารถใช้งานได้ผ่าน GUI:

  • -r: แทนที่แอปที่มีอยู่ (อนุญาตให้ติดตั้งใหม่)
  • -d: อนุญาตให้ดาวน์เกรดเวอร์ชัน
  • -g: ให้สิทธิ์รันไทม์ทั้งหมดทันที
  • -t: อนุญาตให้ติดตั้ง APK สำหรับการทดสอบเท่านั้น
  • --install-multiple: ติดตั้ง APK แบบแยกในเซสชันเดียว

จะเกิดอะไรขึ้นระหว่างการถอนการติดตั้ง

เพื่อความสมบูรณ์ นี่คือสิ่งที่จะเกิดขึ้นเมื่อมีการลบแอป:

  1. กระบวนการของแอปถูกหยุดทำงาน
  2. APK และไลบรารีที่แตกออกมาจะถูกลบออกจาก /data/app/
  3. ไดเร็กทอรีข้อมูลส่วนตัวของแอปจะถูกลบออก (เว้นแต่ผู้ใช้จะเลือกที่จะเก็บข้อมูล)
  4. ไฟล์แคช DEX ที่คอมไพล์แล้วจะถูกลบ
  5. ฐานข้อมูลแพ็คเกจได้รับการอัพเดต
  6. การออกอากาศ PACKAGE_REMOVED จะถูกส่งไป
  7. ตัวเรียกใช้งานจะลบไอคอนแอป

โปรดทราบว่าไฟล์เฉพาะแอปบนที่จัดเก็บข้อมูลภายนอก (/Android/data/[package]/ และ /Android/obb/[package]/ จะถูกลบใน Android 10 และใหม่กว่าด้วย ด้วยการบังคับใช้พื้นที่เก็บข้อมูลแบบกำหนดขอบเขต)

เหตุใดการทำความเข้าใจ PackageManager จึงช่วยประหยัดเวลาในการดีบัก

กระบวนการติดตั้ง Android เป็นลำดับการตรวจสอบความปลอดภัย การทำงานของไฟล์ และการรวมระบบที่จัดทำขึ้นอย่างระมัดระวัง แต่ละขั้นตอนมีจุดมุ่งหมาย ตั้งแต่การปกป้องผู้ใช้จากแอปที่ถูกดัดแปลงไปจนถึงการปรับประสิทธิภาพให้เหมาะสมสำหรับฮาร์ดแวร์เฉพาะ เมื่อการติดตั้งล้มเหลว ข้อผิดพลาดมักจะชี้ไปที่ขั้นตอนเฉพาะในไปป์ไลน์นี้ และการทำความเข้าใจกระบวนการนี้จะช่วยให้คุณวินิจฉัยและแก้ไขปัญหาได้อย่างรวดเร็ว

การติดตั้งจาก Play Store, ไซด์โหลด APK ด้วยมือ และพุชบิลด์ด้วย ADB ช่องทางทั้งหมดผ่านไปป์ไลน์พื้นฐานเดียวกัน ซึ่งเป็นช่องทางที่ทำให้แน่ใจว่าทุกแอปบนอุปกรณ์ของคุณได้รับการตรวจสอบ วางอย่างถูกต้อง และปรับให้เหมาะกับฮาร์ดแวร์ของคุณ

ออกแบบและจัดทำเอกสารโดย Mst Shaefale หัวหน้านักพัฒนาและสถาปนิกแพ็คเกจ Android • ตรวจสอบแล้วบน Android 12–15

Mst Shaefale ดูแลการควบรวมกิจการ XAPK/APKS ฝั่งไคลเอ็นต์, ตัวแยกวิเคราะห์รายการไบนารี และเครื่องมือลงนาม APK v1+v2 ที่ xapktoapk.com พบคำสั่งที่ล้าสมัยหรือการเปลี่ยนแปลงระบบปฏิบัติการหรือไม่ ส่งบันทึกบรรณาธิการ