Cách cài đặt ứng dụng Android hoạt động dưới mui xe

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

Khi bạn nhấn "Cài đặt" trên tệp APK hoặc tải xuống ứng dụng từ Cửa hàng Play, một chuỗi thao tác phức tạp sẽ bắt đầu ở hậu trường. Thanh tiến trình trông có vẻ đơn giản thực ra thể hiện hàng chục bước liên quan đến phân tích gói, xác minh mật mã, quản lý quyền, trích xuất tệp và tối ưu hóa mã. Hiểu quy trình này sẽ giúp giải thích tại sao việc cài đặt đôi khi không thành công và bạn có thể làm gì với vấn đề đó.

Trong bài viết này, chúng ta sẽ tìm hiểu từng bước chính trong quy trình cài đặt Android, từ thời điểm hệ thống nhận được APK cho đến thời điểm ứng dụng sẵn sàng khởi chạy.

Bước 1: Bắt đầu cài đặt

Quá trình cài đặt bắt đầu khác nhau tùy thuộc vào nguồn:

  • Cửa hàng Play: Ứng dụng Cửa hàng Play tải xuống APK (hoặc các APK chia nhỏ) và gọi trình cài đặt gói của hệ thống với các đặc quyền bỏ qua một số xác nhận của người dùng.
  • Đang tải: Khi bạn mở tệp APK, Android sẽ khởi chạy hoạt động cài đặt gói. Trên Android 8.0 trở lên, ứng dụng cài đặt phải có quyền "Cài đặt ứng dụng không xác định" đối với nguồn cụ thể của nó.
  • ADB: Lệnh adb install giao tiếp trực tiếp với dịch vụ quản lý gói qua USB, bỏ qua hoàn toàn trình cài đặt đồ họa.

Bất kể nguồn nào, tất cả các cài đặt cuối cùng đều đạt đến cùng một dịch vụ hệ thống: Dịch vụ quản lý gói (PMS). Đây là cơ quan trung ương cho tất cả các hoạt động gói trên Android.

Bước 2: Phân tích gói

Trước hết, hệ thống cần hiểu những gì nó sắp cài đặt. PackageManagerService gọi Trình phân tích gói để đọc tệp APK và trích xuất siêu dữ liệu của nó.

Trình phân tích cú pháp đọc tệp AndroidManifest.xml từ trong APK. Tệp XML nhị phân này chứa thông tin quan trọng:

  • Tên gói: Mã định danh duy nhất cho ứng dụng (ví dụ: com.example.myapp)
  • Mã phiên bản và tên: Được sử dụng để xác định xem đây là bản nâng cấp hay bản cài đặt mới
  • Phiên bản SDK tối thiểu và mục tiêu: Xác định khả năng tương thích với thiết bị
  • Quyền được khai báo: Cả hai quyền mà ứng dụng yêu cầu và các quyền tùy chỉnh mà nó xác định
  • thành phần: Các hoạt động, dịch vụ, bộ thu phát sóng và nhà cung cấp nội dung mà ứng dụng đăng ký
  • Tính năng phần cứng và phần mềm: Các yêu cầu như máy ảnh, GPS hoặc các phiên bản OpenGL cụ thể

Nếu tệp kê khai không đúng định dạng hoặc cấu trúc APK không hợp lệ thì quá trình cài đặt sẽ không thành công ở giai đoạn này với thông báo "Lỗi phân tích cú pháp". Đây là một trong những lý do phổ biến nhất khiến APK đã tải sẵn không cài đặt được.

Bước 3: Kiểm tra tính tương thích

Sau khi tệp kê khai được phân tích cú pháp, hệ thống sẽ thực hiện một loạt kiểm tra tính tương thích:

  • Phiên bản SDK: Nếu minSdkVersion của ứng dụng cao hơn cấp API của thiết bị thì quá trình cài đặt sẽ bị từ chối.
  • Khả năng tương thích ABI: Nếu APK chứa các thư viện gốc thì hệ thống sẽ kiểm tra xem chúng có khớp với kiến trúc CPU của thiết bị hay không. APK chỉ có thư viện armeabi-v7a sẽ không cài đặt trên thiết bị chỉ x86.
  • Các tính năng cần thiết: Nếu ứng dụng khai báo các tính năng phần cứng bắt buộc (như android.hardware.telephony), hệ thống sẽ xác minh thiết bị hỗ trợ các tính năng đó.
  • Lưu trữ có sẵn: Hệ thống kiểm tra xem có đủ dung lượng trống để cài đặt ứng dụng hay không, bao gồm dung lượng cho các thư viện gốc được trích xuất và các tệp DEX được tối ưu hóa.

Bước 4: Xác minh chữ ký

Đây là một trong những bước quan trọng nhất trong quá trình cài đặt. Android xác minh chữ ký mật mã của APK để đảm bảo tính toàn vẹn và xác thực của APK.

Quá trình xác minh phụ thuộc vào các chương trình ký kết hiện có:

Chữ ký V1 (Ký JAR)

Hệ thống kiểm tra thư mục META-INF/ để tìm các tệp chữ ký (.SF, .RSA hoặc .DSA). Mỗi tệp trong APK đều được xác minh dựa trên các thông báo tóm tắt được liệt kê trong tệp kê khai. Quá trình này chậm vì mỗi tệp phải được băm riêng lẻ.

Chữ ký V2 (Lược đồ chữ ký APK v2)

Được giới thiệu trong Android 7.0, lược đồ này ký toàn bộ APK dưới dạng blob nhị phân. Khối chữ ký được chèn vào giữa thư mục trung tâm ZIP và bản ghi cuối thư mục trung tâm. Việc xác minh nhanh hơn nhiều vì nó hoạt động trên các byte thô mà không cần giải nén các mục riêng lẻ.

Chữ ký V3 (Xoay phím)

Có sẵn từ Android 9.0, V3 mở rộng V2 với sự hỗ trợ xoay phím. Nó bao gồm cấu trúc bằng chứng luân chuyển liên kết các khóa ký cũ và mới, cho phép các nhà phát triển thay đổi khóa ký của họ trong khi vẫn duy trì khả năng tương thích của bản cập nhật.

Chữ ký V4 (Tăng dần)

Android 11 đã giới thiệu V4 cho các lượt cài đặt tăng dần. Nó cung cấp chữ ký dựa trên cây Merkle cho phép xác minh các khối riêng lẻ khi chúng được truyền tới thiết bị.

Nếu việc xác minh chữ ký không thành công vì bất kỳ lý do nào, quá trình cài đặt sẽ bị hủy ngay lập tức. Bạn có thể kiểm tra chữ ký của APK trước khi cài đặt bằng Công cụ xác minh APK của chúng tôi.

Cập nhật khớp chữ ký

Nếu ứng dụng có cùng tên gói đã được cài đặt, hệ thống sẽ thực hiện kiểm tra bổ sung: chứng chỉ ký của APK mới phải khớp với chứng chỉ của bản cài đặt hiện có. Điều này ngăn chặn bên độc hại thay thế ứng dụng hợp pháp bằng phiên bản giả mạo. Nếu chữ ký không khớp, bạn sẽ thấy lỗi "Ứng dụng chưa được cài đặt: Gói xung đột với gói hiện có cùng tên."

Bước 5: Xác nhận người dùng

Đối với các cài đặt được tải sẵn, hệ thống sẽ hiển thị hộp thoại xác nhận cài đặt hiển thị:

  • Tên và biểu tượng ứng dụng (được trích từ tài nguyên của APK)
  • Cấp quyền mà ứng dụng yêu cầu (trên các phiên bản Android cũ hơn)
  • Cho dù đây là bản cài đặt mới hay bản cập nhật
  • Mọi cảnh báo về nguồn ứng dụng hoặc rủi ro tiềm ẩn

Trên Android 12 trở lên, màn hình xác nhận đơn giản hơn vì các quyền trong thời gian chạy được cấp riêng lẻ khi ứng dụng cần chúng lần đầu tiên, thay vì tại thời điểm cài đặt.

Bước 6: Trích xuất và đặt tệp

Sau khi người dùng xác nhận (hoặc tự động cài đặt Cửa hàng Play), hệ thống sẽ bắt đầu giải nén và đặt tệp:

Lưu trữ APK

Bản thân tệp APK được sao chép vào /data/app/[package-name]-[random]/base.apk. Để cài đặt APK chia nhỏ, các tệp bổ sung như split_config.arm64_v8a.apk được đặt cùng với APK cơ sở. APK gốc trong thư mục Tải xuống không bị sửa đổi hoặc xóa.

Khai thác thư viện gốc

Nếu APK chứa các thư viện gốc (trong thư mục lib/, chúng sẽ được trích xuất thành /data/app/[package-name]-[random]/lib/[abi]/). Trên các phiên bản Android mới hơn, ứng dụng có thể chọn giữ các thư viện gốc được nén trong APK và tải chúng trực tiếp bằng android:extractNativeLibs="false", giúp tiết kiệm dung lượng lưu trữ.

Tạo thư mục dữ liệu

Hệ thống tạo thư mục dữ liệu riêng tư của ứng dụng tại /data/data/[package-name]/ (hoặc /data/user/0/[package-name]/ trên thiết bị nhiều người dùng). Thư mục này được sở hữu bởi một UID Linux duy nhất được gán cho ứng dụng, đảm bảo không ứng dụng nào khác có thể truy cập nó nếu không có quyền root.

Bước 7: Tối ưu hóa DEX

Bước này là nơi Android chuyển đổi mã byte của ứng dụng thành định dạng được tối ưu hóa cho phần cứng cụ thể của thiết bị. Quá trình này đã phát triển đáng kể trong lịch sử của Android:

Kỷ nguyên Dalvik (Android 4.4 trở về trước)

Máy ảo Dalvik ban đầu sử dụng trình biên dịch Just-In-Time (JIT). Trong quá trình cài đặt, tệp classes.dex đã được tối ưu hóa thành tệp ODEX chứa mã byte được xác minh và tối ưu hóa. Điều này tương đối nhanh nhưng có nghĩa là ứng dụng chạy chậm hơn trong thời gian chạy vì hầu hết mã vẫn được diễn giải.

NGHỆ THUẬT với AOT (Android 5.0 đến 6.0)

Android Runtime (ART) đã thay thế Dalvik và giới thiệu tính năng biên dịch Ahead-Of-Time (AOT). Trong quá trình cài đặt, toàn bộ mã byte DEX được biên dịch thành mã máy gốc. Điều này làm cho ứng dụng chạy nhanh hơn nhưng tăng đáng kể thời gian cài đặt và mức sử dụng bộ nhớ. Một số ứng dụng mất vài phút để cài đặt.

Biên soạn theo hướng dẫn hồ sơ (Android 7.0+)

Android hiện đại sử dụng phương pháp kết hợp. Trong quá trình cài đặt, chỉ các đường dẫn khởi động quan trọng mới được biên dịch. Khi người dùng chạy ứng dụng, hệ thống sẽ thu thập hồ sơ thực thi xác định các đường dẫn mã được sử dụng thường xuyên. Trong thời gian bảo trì không tải (thường là sạc qua đêm), hệ thống sẽ biên dịch các đường dẫn nóng này thành mã gốc. Điều này cân bằng tốc độ cài đặt, mức sử dụng bộ nhớ và hiệu suất thời gian chạy.

Mã đã biên dịch được lưu trữ trong /data/dalvik-cache/ hoặc cùng với APK dưới dạng các tệp .odex, .vdex và .art. Tệp .vdex chứa mã DEX đã được xác minh, tệp .odex chứa mã gốc được biên dịch và tệp .art chứa hình ảnh heap được khởi tạo trước để khởi động nhanh hơn.

Bước 8: Đăng ký quyền

PackageManagerService đăng ký các quyền và thành phần đã khai báo của ứng dụng với hệ thống:

  • Quyền tại thời điểm cài đặt (như INTERNET hoặc VIBRATE được cấp tự động mà không cần sự tương tác của người dùng).
  • Quyền thời gian chạy (như CAMERA hoặc LOCATION đã được đăng ký nhưng không được cấp). Ứng dụng phải yêu cầu chúng khi chạy.
  • Bộ lọc ý định được đăng ký để hệ thống biết ứng dụng nào có thể xử lý hành động nào (như mở URL hoặc chia sẻ nội dung).
  • Nhà cung cấp nội dung được đăng ký với cơ quan có thẩm quyền của họ để các ứng dụng khác có thể truy vấn chúng.

Bước 9: Tích hợp hệ thống

Các bước cuối cùng tích hợp ứng dụng vào hệ thống Android:

  • Cập nhật cơ sở dữ liệu gói: Cơ sở dữ liệu gói của hệ thống (/data/system/packages.xml) được cập nhật với thông tin của ứng dụng mới, bao gồm UID được chỉ định, quyền và khai báo thành phần.
  • Thông báo trình khởi chạy: Trình khởi chạy màn hình chính được thông báo về ứng dụng mới để nó có thể hiển thị biểu tượng ứng dụng.
  • Phát tin: Hệ thống gửi một chương trình phát sóng PACKAGE_ADDED, cho phép các ứng dụng khác phản ứng với cài đặt mới (ví dụ: các ứng dụng sao lưu có thể lên lịch sao lưu).
  • Bối cảnh SELinux: Các tệp của ứng dụng được gắn nhãn bối cảnh bảo mật SELinux thích hợp dựa trên phiên bản SDK mục tiêu và các quyền đã khai báo.

Tại sao cài đặt thất bại

Hiểu quy trình cài đặt giúp chẩn đoán các lỗi thường gặp:

  • "Lỗi phân tích cú pháp": APK bị hỏng, không đầy đủ hoặc có tệp kê khai không đúng định dạng. Điều này thường xảy ra với các bản tải xuống không đầy đủ hoặc các tệp được chuyển đổi không đúng cách.
  • "Ứng dụng chưa được cài đặt" (chữ ký không khớp): Bạn đang cố cập nhật ứng dụng bằng APK được ký bằng một khóa khác. Trước tiên, bạn phải gỡ cài đặt phiên bản hiện có.
  • "Không đủ dung lượng lưu trữ": Không đủ dung lượng cho APK, thư viện được trích xuất và đầu ra tối ưu hóa DEX. Dung lượng thực tế cần thiết thường gấp 2-3 lần kích thước APK.
  • "Gói xung đột với gói hiện tại": Cùng tên gói nhưng chữ ký khác nhau. Phổ biến khi chuyển đổi giữa Play Store và các phiên bản được tải sẵn.
  • Đã chặn hạ cấp phiên bản: Theo mặc định, Android ngăn cài đặt phiên bản cũ hơn phiên bản mới hơn. ADB có thể ghi đè điều này bằng adb install -d.

Tách cài đặt APK

Khi cài đặt APK chia nhỏ (từ Gói ứng dụng), quy trình sẽ hơi khác một chút. Hệ thống sử dụng API cài đặt dựa trên phiên:

  1. Một phiên cài đặt mới được tạo
  2. Mỗi APK phân chia được ghi vào phiên
  3. Phiên được cam kết, kích hoạt quy trình xác minh đầy đủ
  4. Tất cả các phần tách phải có tên gói, mã phiên bản và chứng chỉ ký trùng khớp

Đây là cơ chế được sử dụng bởi các trình cài đặt XAPK và các công cụ như Hợp nhất APKS thành APK của chúng tôi để xử lý các cài đặt nhiều tệp.

Cài đặt qua ADB

Khi bạn sử dụng adb install, quy trình sẽ bỏ qua trình cài đặt đồ họa nhưng tuân theo cùng một quy trình nội bộ. ADB giao tiếp với dịch vụ quản lý gói thông qua kết nối ổ cắm. Nó hỗ trợ các cờ bổ sung không có sẵn thông qua GUI:

  • -r: Thay thế ứng dụng hiện có (cho phép cài đặt lại)
  • -d: Cho phép hạ cấp phiên bản
  • -g: Cấp ngay lập tức tất cả các quyền trong thời gian chạy
  • -t: Cho phép cài đặt APK chỉ dùng thử nghiệm
  • --install-multiple: Cài đặt các APK chia nhỏ trong một phiên duy nhất

Điều gì xảy ra trong quá trình gỡ cài đặt

Để đầy đủ hơn, đây là những gì xảy ra khi một ứng dụng bị xóa:

  1. Các quy trình của ứng dụng bị hủy
  2. APK và thư viện giải nén sẽ bị xóa khỏi /data/app/
  3. Thư mục dữ liệu riêng tư của ứng dụng sẽ bị xóa (trừ khi người dùng chọn giữ lại dữ liệu)
  4. Các tệp bộ đệm DEX đã biên dịch sẽ bị xóa
  5. Cơ sở dữ liệu gói được cập nhật
  6. Một chương trình phát sóng PACKAGE_REMOVED được gửi
  7. Trình khởi chạy xóa biểu tượng ứng dụng

Xin lưu ý rằng các tệp dành riêng cho ứng dụng trên bộ nhớ ngoài (/Android/data/[package]/ và /Android/obb/[package]/ cũng bị xóa trên Android 10 trở lên nhờ thực thi bộ nhớ trong phạm vi).

Tại sao hiểu PackageManager lại tiết kiệm thời gian gỡ lỗi

Quá trình cài đặt Android là một chuỗi các bước kiểm tra bảo mật, thao tác tệp và tích hợp hệ thống được sắp xếp cẩn thận. Mỗi bước phục vụ một mục đích, từ việc bảo vệ người dùng khỏi các ứng dụng giả mạo cho đến tối ưu hóa hiệu suất cho phần cứng cụ thể. Khi quá trình cài đặt không thành công, lỗi thường chỉ ra một bước cụ thể trong quy trình này và việc hiểu rõ quy trình sẽ giúp bạn chẩn đoán và giải quyết vấn đề nhanh chóng.

Cài đặt từ Cửa hàng Play, tải APK thủ công và đẩy toàn bộ kênh xây dựng bằng ADB thông qua cùng một quy trình cơ bản, quy trình đảm bảo mọi ứng dụng trên thiết bị của bạn đều đã được xác minh, đặt chính xác và tối ưu hóa cho phần cứng của bạn.

Được thiết kế và ghi lại bởi Mst Shaefale Nhà phát triển chính và Kiến trúc sư gói Android • Đã xác minh trên Android 12–15

Bà Shaefale duy trì việc hợp nhất XAPK/APKS phía máy khách, trình phân tích cú pháp tệp kê khai nhị phân và các công cụ ký APK v1+v2 tại xapktoapk.com. Phát hiện lệnh đã lỗi thời hoặc thay đổi hệ điều hành? Gửi một ghi chú biên tập.