Nguyên tắc cơ bản về ứng dụng

Ứng dụng Android có thể được viết bằng Kotlin, ngôn ngữ lập trình Java và ngôn ngữ C++. Công cụ SDK Android biên dịch mã của bạn cùng với mọi tệp dữ liệu và tài nguyên vào một APK hoặc Android App Bundle.

Gói Android, là một tệp lưu trữ có hậu tố .apk, chứa nội dung của ứng dụng Android cần có trong thời gian chạy và đó là tệp mà Android hỗ trợ thiết bị sử dụng để cài đặt ứng dụng.

Android App Bundle là một tệp lưu trữ có hậu tố .aab, chứa nội dung của dự án ứng dụng Android, bao gồm cả một số siêu dữ liệu bổ sung không bắt buộc tại thời gian chạy. AAB là một định dạng xuất bản và không thể cài đặt trên thiết bị Android. Nó trì hoãn việc tạo tệp APK và ký chuyển sang giai đoạn sau.

Khi phân phối ứng dụng thông qua Google Ví dụ: máy chủ của Google Play tạo các tệp APK được tối ưu hoá chỉ chứa những tài nguyên và mà thiết bị cụ thể yêu cầu cài đặt ứng dụng yêu cầu.

Mỗi ứng dụng Android đều có một hộp cát bảo mật riêng, được bảo vệ bằng các tính năng bảo mật sau đây của Android:

  • Hệ điều hành Android là một hệ điều hành Linux nhiều người dùng, trong đó mỗi ứng dụng là một người dùng khác nhau.
  • Theo mặc định, hệ thống chỉ định cho mỗi ứng dụng một mã nhận dạng người dùng Linux duy nhất, mã này chỉ được hệ thống mà ứng dụng không xác định được. Hệ thống đặt quyền cho tất cả các tệp trong một sao cho chỉ mã nhận dạng người dùng được gán cho ứng dụng đó mới có thể truy cập vào các ứng dụng đó.
  • Mỗi quy trình có máy ảo (VM) riêng, do đó, mã của ứng dụng sẽ chạy độc lập với các ứng dụng khác.
  • Theo mặc định, mỗi ứng dụng đều chạy ở quy trình Linux riêng. Hệ thống Android khởi động khi bất kỳ thành phần của ứng dụng cần được thực thi, sau đó tắt quy trình khi không còn nữa cần thiết hoặc khi hệ thống phải khôi phục bộ nhớ cho các ứng dụng khác.

Hệ thống Android triển khai nguyên tắc về đặc quyền tối thiểu. Tức là theo mặc định, mỗi ứng dụng chỉ có quyền truy cập vào các thành phần mà ứng dụng cần để thực hiện công việc của mình và không còn nữa. Việc này tạo ra một môi trường rất an toàn trong đó ứng dụng không thể truy cập vào các phần của hệ thống mà nó không được cấp quyền.

Tuy nhiên, có nhiều cách để ứng dụng chia sẻ với các ứng dụng khác và cho một ứng dụng để truy cập vào các dịch vụ của hệ thống:

  • Có thể sắp xếp để hai ứng dụng chia sẻ cùng một mã nhận dạng người dùng Linux. Trong trường hợp đó, họ có thể truy cập vào tệp của nhau. Để tiết kiệm tài nguyên hệ thống, các ứng dụng có cùng một mã nhận dạng người dùng cũng có thể được sắp xếp để chạy trong cùng một quy trình Linux và dùng chung cùng một máy ảo. Chiến lược phát hành đĩa đơn ứng dụng nào cũng phải được ký bằng cùng một chứng chỉ.
  • Ứng dụng có thể yêu cầu quyền truy cập vào dữ liệu thiết bị chẳng hạn như vị trí, máy ảnh và kết nối Bluetooth. Người dùng có để cấp các quyền này một cách rõ ràng. Để biết thêm thông tin về các quyền, hãy xem Quyền trên Android.

Phần còn lại của tài liệu này giới thiệu các khái niệm sau:

  • Các thành phần khung cốt lõi xác định ứng dụng của bạn.
  • Tệp kê khai trong đó bạn khai báo các thành phần và thiết bị được yêu cầu cho .
  • Tài nguyên tách biệt với mã ứng dụng và cho phép ứng dụng của bạn tối ưu hoá hành vi một cách linh hoạt cho nhiều cấu hình thiết bị.

Thành phần ứng dụng

Thành phần ứng dụng là thành phần thiết yếu của ứng dụng Android. Một thành phần là điểm truy cập mà qua đó hệ thống hoặc người dùng có thể truy cập vào ứng dụng của bạn. Hơi nhiều thành phần phụ thuộc vào các thành phần khác.

Có 4 loại thành phần ứng dụng:

  • Hoạt động
  • Dịch vụ
  • Broadcast receiver
  • Trình cung cấp nội dung

Mỗi loại phục vụ một mục đích riêng biệt đồng thời có một vòng đời riêng biệt xác định cách tạo và huỷ một thành phần. Các phần sau đây mô tả 4 loại thành phần ứng dụng.

Hoạt động
Một hoạt động là điểm truy cập để tương tác với người dùng. Nó đại diện cho một có giao diện người dùng. Ví dụ: ứng dụng email có thể có một hoạt động hiển thị danh sách email, một hoạt động khác để soạn email và một hoạt động khác để đọc email. Mặc dù các hoạt động phối hợp với nhau để tạo thành trải nghiệm người dùng gắn kết trong ứng dụng email, mỗi hoạt động độc lập với các yếu tố khác.

Một ứng dụng khác có thể khởi động bất kỳ hành động nào trong số này nếu ứng dụng email cho phép. Ví dụ: ứng dụng máy ảnh có thể khởi động hoạt động trong ứng dụng email để soạn email mới nhằm cho phép người dùng chia sẻ ảnh.

Một hoạt động hỗ trợ các hoạt động tương tác chính sau đây giữa hệ thống và ứng dụng:

  • Theo dõi những gì người dùng đang quan tâm (nội dung trên màn hình) để tiếp tục chạy quy trình lưu trữ hoạt động đó.
  • Biết được quy trình nào được sử dụng trước đó chứa các hoạt động đã dừng mà người dùng có thể quay lại và ưu tiên các quy trình đó cao hơn để đảm bảo chúng luôn sẵn sàng.
  • Giúp ứng dụng xử lý việc dừng quy trình để người dùng có thể quay lại các hoạt động khi trạng thái trước đó được khôi phục.
  • Cung cấp một cách để các ứng dụng triển khai luồng người dùng với nhau và để hệ thống có thể điều phối các luồng này. Ví dụ chính cho phương pháp này là chia sẻ.

Bạn triển khai một hoạt động dưới dạng lớp con của lớp Activity. Để biết thêm thông tin về lớp Activity, hãy xem Giới thiệu về hoạt động.

Dịch vụ
Dịch vụ là một điểm truy cập đa năng để duy trì ứng dụng chạy ở chế độ nền vì mọi lý do. Đây là một thành phần chạy ở chế độ nền để hoạt động trong thời gian dài các thao tác hoặc thực hiện công việc cho các quy trình từ xa. Dịch vụ không cung cấp giao diện người dùng.

Cho ví dụ: một dịch vụ có thể phát nhạc trong nền khi người dùng đang dùng một ứng dụng khác, hoặc nó có thể tìm nạp dữ liệu qua mạng mà không chặn tương tác của người dùng với một hoạt động. Khác thành phần, chẳng hạn như một hoạt động, có thể khởi động dịch vụ và cho phép dịch vụ chạy hoặc liên kết với tương tác với thiết bị đó.

Có 2 loại dịch vụ cho hệ thống biết cách quản lý một ứng dụng: dịch vụ đã bắt đầu và các dịch vụ ràng buộc.

Các dịch vụ đã bắt đầu yêu cầu hệ thống tiếp tục chạy cho đến khi công việc hoàn tất. Thao tác này có thể là đồng bộ hoá một số dữ liệu trong nền hoặc phát nhạc ngay cả sau khi người dùng rời khỏi ứng dụng. Việc đồng bộ hoá dữ liệu ở chế độ nền hoặc phát nhạc thể hiện nhiều kiểu thời điểm bắt đầu các dịch vụ mà hệ thống xử lý theo cách khác:

  • Phát nhạc là tính năng mà người dùng trực tiếp nhận biết được và ứng dụng sẽ truyền thông tin này đến hệ thống bằng cách chỉ ra rằng nó muốn ở nền trước, kèm theo một thông báo để cho cho người dùng mà ứng dụng đang chạy. Trong trường hợp này, hệ thống sẽ ưu tiên việc duy trì đang chạy vì người dùng có trải nghiệm không tốt nếu quá trình đó biến mất.
  • Dịch vụ nền thông thường không phải là dịch vụ mà người dùng trực tiếp biết được, vì vậy hệ thống có thể tự do hơn trong việc quản lý quy trình của mình. Có thể nó sẽ bị giết, khởi động lại dịch vụ sau này, nếu cần RAM cho những tính năng mối quan tâm tức thì cho người dùng.

Dịch vụ ràng buộc chạy vì một số ứng dụng khác (hoặc hệ thống) đã cho biết rằng ứng dụng đó muốn sử dụng . Dịch vụ ràng buộc cung cấp API cho một quy trình khác và hệ thống biết rằng có sự phụ thuộc giữa các quy trình này. Vì vậy, nếu quá trình A liên kết với một dịch vụ trong tiến trình B, hệ thống biết rằng cần duy trì quá trình B và dịch vụ của nó chạy cho A. Ngoài ra, nếu quá trình A là điều mà người dùng quan tâm, thì quá trình này biết rằng quá trình B là điều gì đó người dùng cũng quan tâm.

Do tính linh hoạt nên các dịch vụ rất hữu ích nền tảng cho tất cả các loại khái niệm hệ thống cấp cao hơn. Hình nền động, thông báo trình nghe, trình bảo vệ màn hình, phương thức nhập, dịch vụ hỗ trợ tiếp cận và nhiều tính năng hệ thống cốt lõi khác đều được xây dựng dưới dạng dịch vụ mà các ứng dụng triển khai và hệ thống sẽ liên kết với khi chúng chạy.

Dịch vụ được triển khai dưới dạng lớp con của Service. Thông tin khác về lớp Service, hãy xem Tổng quan về dịch vụ.

Lưu ý: Nếu ứng dụng của bạn nhắm đến Android 5.0 (API cấp 21) trở lên, sử dụng lớp JobScheduler để lên lịch cho hành động. JobScheduler có tận dụng tiết kiệm pin bằng cách lên lịch công việc một cách tối ưu nhằm giảm mức tiêu thụ điện năng và bằng cách làm việc với API Doze. Để biết thêm thông tin về cách sử dụng lớp này, hãy xem JobScheduler tài liệu tham khảo.

Bộ nhận tín hiệu truyền tin
broadcast receiver là một thành phần cho phép hệ thống phân phối sự kiện đến ứng dụng nằm ngoài luồng người dùng thông thường để ứng dụng có thể phản hồi thông báo truyền phát trên toàn hệ thống thông báo. Vì broadcast receiver là một mục nhập được xác định rõ khác vào ứng dụng, nên hệ thống có thể phân phối thông báo ngay cả tới những ứng dụng hiện không chạy.

Ví dụ: một ứng dụng có thể lên lịch báo thức để đăng thông báo cho người dùng biết về sự kiện sắp tới. Vì chuông báo được gửi đến BroadcastReceiver trong ứng dụng nên ứng dụng không cần phải sẽ tiếp tục chạy cho đến khi chuông báo kêu.

Nhiều thông báo truyền tin bắt nguồn từ hệ thống, chẳng hạn như một chương trình phát đi thông báo rằng màn hình đã tắt, pin yếu hoặc đã chụp ảnh. Các ứng dụng cũng có thể bắt đầu thông báo, chẳng hạn như để cho các ứng dụng khác biết rằng một số dữ liệu được tải xuống thiết bị và có sẵn để sử dụng.

Mặc dù phát sóng các receiver không hiển thị giao diện người dùng, mà có thể tạo thông báo trên thanh trạng thái để cảnh báo cho người dùng khi một sự kiện truyền tin xảy ra. Tuy nhiên, broadcast receiver phổ biến hơn chỉ là một cổng dẫn đến các thành phần khác và nhằm thực hiện lượng công việc rất nhỏ.

Ví dụ: một broadcast receiver có thể lên lịch để JobService thực hiện một số công việc dựa trên cho một sự kiện bằng JobScheduler. Broadcast receiver thường liên quan đến các ứng dụng tương tác với nhau, vì vậy, bạn cần lưu ý những tác động về bảo mật khi thiết lập chúng.

Broadcast receiver được triển khai dưới dạng lớp con của BroadcastReceiver, và mỗi thông báo truyền tin được phân phối dưới dạng một đối tượng Intent. Để biết thêm thông tin, xem lớp BroadcastReceiver.

Nhà cung cấp nội dung
Nhà cung cấp nội dung quản lý tập dữ liệu ứng dụng dùng chung mà bạn có thể lưu trữ trong đó hệ thống tệp, trong cơ sở dữ liệu SQLite, trên web hoặc trên bất kỳ bộ nhớ cố định nào khác mà ứng dụng có thể truy cập. Thông qua trình cung cấp nội dung, các ứng dụng khác có thể truy vấn hoặc sửa đổi dữ liệu nếu nhà cung cấp nội dung cho phép.

Ví dụ: hệ thống Android cung cấp một nội dung quản lý thông tin liên hệ của người dùng. Bất kỳ ứng dụng nào có có thể truy vấn trình cung cấp nội dung, chẳng hạn như sử dụng ContactsContract.Data để đọc và ghi thông tin về một người cụ thể.

Bạn nên coi trình cung cấp nội dung là một yếu tố trừu tượng trên cơ sở dữ liệu, vì có một rất nhiều API và tính năng hỗ trợ được tích hợp sẵn cho trường hợp phổ biến đó. Tuy nhiên, chúng có mục đích cốt lõi từ góc độ thiết kế hệ thống.

Đối với hệ thống, nhà cung cấp nội dung là một điểm truy cập vào một ứng dụng để xuất bản các mục dữ liệu có tên, được xác định bởi một giao thức URI. Do đó, ứng dụng có thể quyết định cách ứng dụng muốn ánh xạ dữ liệu chứa trong đó Không gian tên URI, phân phối các URI đó cho các thực thể khác, từ đó có thể sử dụng chúng để truy cập vào . Có một số chức năng cụ thể mà công cụ này cho phép hệ thống thực hiện trong việc quản lý ứng dụng:

  • Việc chỉ định URI không đòi hỏi ứng dụng phải tiếp tục chạy, vì vậy URI có thể tồn tại sau khi đang sở hữu ứng dụng thoát. Hệ thống chỉ cần đảm bảo rằng một ứng dụng sở hữu vẫn chạy khi truy xuất dữ liệu của ứng dụng từ URI tương ứng.
  • Các URI này cũng cung cấp một mô hình bảo mật chi tiết quan trọng. Ví dụ: một ứng dụng có thể đặt URI cho hình ảnh có trên bảng nhớ tạm, nhưng vẫn để nguyên nội dung nhà cung cấp đã khoá để các ứng dụng khác không thể tự do truy cập vào. Khi ứng dụng thứ hai thử dùng truy cập URI đó trên bảng nhớ tạm, hệ thống có thể cho phép ứng dụng đó truy cập vào dữ liệu bằng cách cấp quyền URI tạm thời để chỉ truy cập dữ liệu sau URI đó và không truy cập gì khác trong ứng dụng thứ hai.

Trình cung cấp nội dung cũng hữu ích cho việc đọc và ghi dữ liệu dành riêng cho bạn và không được chia sẻ.

Trình cung cấp nội dung được triển khai dưới dạng lớp con của ContentProvider và phải triển khai một bộ API chuẩn cho phép các ứng dụng khác hoạt động giao dịch. Để biết thêm thông tin, hãy xem nhà phát triển Nhà cung cấp nội dung của chúng tôi.

Một khía cạnh độc đáo trong thiết kế của hệ thống Android là bất kỳ ứng dụng nào cũng có thể khởi động một của ứng dụng. Ví dụ: nếu bạn muốn người dùng nắm bắt được bằng camera của thiết bị, có thể có một ứng dụng khác làm việc đó—và có thể sử dụng thông tin đó thay vì phát triển một hoạt động để tự chụp ảnh. Không cần kết hợp hoặc thậm chí là liên kết với mã từ ứng dụng máy ảnh. Thay vào đó, bạn có thể bắt đầu hoạt động trong ứng dụng máy ảnh chụp ảnh. Khi hoàn tất, ảnh thậm chí còn được trả về ứng dụng của bạn để bạn có thể sử dụng. Đối với người dùng, có vẻ như camera thực sự là một phần trong ứng dụng của bạn.

Khi khởi động một thành phần nào đó, hệ thống sẽ khởi động quy trình cho ứng dụng đó nếu chưa đã chạy và tạo thực thể cho các lớp cần thiết cho thành phần này. Ví dụ: nếu ứng dụng bắt đầu hoạt động trong ứng dụng máy ảnh chụp ảnh, hoạt động đó chạy trong quy trình thuộc ứng dụng camera chứ không phải trong quy trình của ứng dụng. Do đó, không giống như ứng dụng trên hầu hết các hệ thống khác, ứng dụng Android không có một mục nhập duy nhất điểm: không có hàm main().

Do hệ thống chạy mỗi ứng dụng trong một quy trình riêng biệt với các quyền đối với tệp hạn chế quyền truy cập vào các ứng dụng khác, ứng dụng của bạn không thể kích hoạt trực tiếp một thành phần từ một ứng dụng khác. Tuy nhiên, hệ thống Android có thể. Cách kích hoạt một thành phần trong một ứng dụng khác, bạn gửi thông báo đến hệ thống để chỉ định ý định của bạn cho khởi động một thành phần cụ thể. Sau đó, hệ thống sẽ kích hoạt thành phần này cho bạn.

Kích hoạt các thành phần

Một thông báo không đồng bộ được gọi là ý định (intent) sẽ kích hoạt 3 trong số 4 loại thành phần: hoạt động, dịch vụ và broadcast receiver. Ý định liên kết các thành phần riêng lẻ với nhau trong thời gian chạy. Bạn có thể nghĩ về dưới dạng trình nhắn tin yêu cầu hành động từ các thành phần khác, cho dù thành phần đó có thuộc đối với ứng dụng của bạn hoặc ứng dụng khác.

Một ý định được tạo bằng đối tượng Intent, đối tượng này xác định một thông báo cho kích hoạt một thành phần cụ thể (ý định rõ ràng) hoặc một loại thành phần cụ thể (ý định ngầm ẩn).

Đối với các hoạt động và dịch vụ, một ý định xác định thao tác cần thực hiện, chẳng hạn như xem hoặc gửi nội dung nào đó và có thể chỉ định URI của dữ liệu để thực hiện hành động, cùng với các thao tác khác đang được bắt đầu có thể cần biết.

Ví dụ: một ý định có thể truyền tải yêu cầu về hiển thị hình ảnh hoặc mở một trang web. Trong một số trường hợp, bạn có thể bắt đầu hoạt động nhận được kết quả. Trong trường hợp đó, hoạt động cũng trả về kết quả trong Intent. Bạn cũng có thể đưa ra một ý định để cho phép người dùng chọn một người liên hệ cá nhân và yêu cầu người liên hệ đó trả lại cho bạn. Ý định trả về bao gồm URI trỏ đến địa chỉ liên hệ đã chọn.

Đối với broadcast receiver, ý định sẽ xác định phát đi thông báo. Ví dụ: một thông báo phát đi thông báo rằng thiết bị sắp hết pin chỉ bao gồm một chuỗi hành động đã biết cho biết pin yếu.

Không giống như hoạt động, dịch vụ và broadcast receiver, nhà cung cấp nội dung được kích hoạt khi được một yêu cầu của ContentResolver nhắm đến. Nội dung trình phân giải xử lý tất cả các giao dịch trực tiếp với nhà cung cấp nội dung và thành phần thực hiện giao dịch với các phương thức gọi của nhà cung cấp trên Đối tượng ContentResolver. Điều này tạo ra một lớp trừu tượng vì lý do bảo mật giữa trình cung cấp nội dung và thành phần yêu cầu thông tin.

Có nhiều phương thức riêng biệt để kích hoạt từng loại thành phần:

  • Bạn có thể bắt đầu một hoạt động hoặc tạo điều kiện mới cho hoạt động đó bằng cách truyền một Intent đến startActivity() hoặc khi bạn muốn hoạt động trả về một kết quả, startActivityForResult().
  • Trên Android 5.0 (API cấp 21) trở lên, bạn có thể sử dụng lớp JobScheduler để lên lịch cho hành động. Đối với các phiên bản Android cũ, bạn có thể bắt đầu một dịch vụ hoặc cung cấp các hướng dẫn mới cho một dịch vụ đang hoạt động bằng cách truyền Intent đến startService(). Bạn có thể liên kết với dịch vụ bằng cách chuyển Intent đến bindService()
  • Bạn có thể bắt đầu truyền tin bằng cách truyền Intent đến các phương thức như sendBroadcast() hoặc sendOrderedBroadcast().
  • Bạn có thể thực hiện truy vấn đến một trình cung cấp nội dung bằng cách gọi query() trên ContentResolver.

Để biết thêm thông tin về cách sử dụng ý định, hãy xem bài viết Ý định và Tài liệu về Bộ lọc ý định. Các tài liệu sau đây cung cấp thêm thông tin về cách kích hoạt các thành phần cụ thể: Giới thiệu về hoạt động, Tổng quan về dịch vụ, BroadcastReceiverTrình cung cấp nội dung.

Tệp kê khai

Trước khi có thể khởi động một thành phần ứng dụng, hệ thống phải biết rằng thành phần tồn tại bằng cách đọc tệp kê khai của ứng dụng, AndroidManifest.xml. Ứng dụng của bạn khai báo tất cả thành phần trong tệp này, đây là thư mục gốc của thư mục dự án ứng dụng.

Tệp kê khai thực hiện một số việc ngoài việc khai báo các thành phần của ứng dụng, chẳng hạn như:

  • Xác định mọi quyền của người dùng mà ứng dụng yêu cầu, chẳng hạn như quyền truy cập Internet hoặc quyền đọc danh bạ của người dùng.
  • Khai báo mức tối thiểu Cấp độ API mà ứng dụng yêu cầu, dựa trên API mà ứng dụng dùng.
  • Khai báo các tính năng phần cứng và phần mềm mà ứng dụng sử dụng hoặc yêu cầu, chẳng hạn như camera, Dịch vụ Bluetooth hoặc màn hình cảm ứng đa điểm.
  • Khai báo các thư viện API mà ứng dụng cần được liên kết (ngoài khung Android) API), chẳng hạn như thư viện Google Maps.

Khai báo thành phần

Nhiệm vụ chính của tệp kê khai là thông báo cho hệ thống về các thành phần của ứng dụng. Cho ví dụ: tệp kê khai có thể khai báo một hoạt động như sau:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>

Trong <application> thì thuộc tính android:icon trỏ đến các tài nguyên của một biểu tượng giúp xác định .

Trong phần tử <activity>, Thuộc tính android:name chỉ định tên lớp đủ điều kiện của lớp con Activity và Thuộc tính android:label chỉ định một chuỗi để dùng làm nhãn hiển thị cho người dùng cho hoạt động.

Bạn phải khai báo tất cả thành phần ứng dụng bằng những phần tử sau:

  • <activity> phần tử cho hoạt động
  • <service> phần tử cho các dịch vụ
  • <receiver> phần tử dành cho broadcast receiver
  • <provider> phần tử dành cho nhà cung cấp nội dung

Hoạt động, dịch vụ và nhà cung cấp nội dung mà bạn đưa vào nguồn của mình nhưng không khai báo trong tệp kê khai không hiển thị với hệ thống và do đó, không bao giờ có thể chạy. Tuy nhiên, truyền tin receiver có thể được khai báo trong tệp kê khai hoặc được tạo động trong mã dưới dạng BroadcastReceiver và được đăng ký với hệ thống bằng cách gọi registerReceiver()

Để biết thêm về cách định cấu trúc tệp kê khai cho ứng dụng, hãy xem nội dung Tổng quan về tệp kê khai ứng dụng.

Khai báo các chức năng của thành phần

Như đã thảo luận trong phần Kích hoạt thành phần, bạn có thể sử dụng Intent để bắt đầu các hoạt động, dịch vụ và broadcast receiver. Bạn thực hiện việc này bằng cách đặt tên rõ ràng cho thành phần mục tiêu, trong đó sử dụng tên lớp thành phần trong ý định. Bạn cũng có thể dùng ý định ngầm ẩn mô tả loại hành động cần thực hiện và dữ liệu mà bạn muốn (không bắt buộc) thực hiện hành động trên đó. Ý định ngầm ẩn cho phép hệ thống tìm một thành phần trên thiết bị có thể thực hiện hành động và bắt đầu hành động đó. Nếu có nhiều thành phần có thể thực hiện tác vụ được mô tả bởi ý định, người dùng chọn một ý định sẽ sử dụng.

Thận trọng: Nếu bạn sử dụng một ý định để bắt đầu một Service, hãy đảm bảo rằng ứng dụng của bạn được bảo mật bằng cách sử dụng phản cảm ý định. Việc sử dụng ý định ngầm ẩn để bắt đầu một dịch vụ mối nguy hiểm về bảo mật vì bạn không thể chắc chắn dịch vụ nào phản hồi ý định đó và người dùng không thể thấy dịch vụ nào bắt đầu. Kể từ Android 5.0 (API cấp 21), hệ thống ném một trường hợp ngoại lệ nếu bạn gọi bindService() có ý định ngầm ẩn. Đừng khai báo bộ lọc ý định cho các dịch vụ.

Hệ thống xác định các thành phần có thể phản hồi một ý định bằng cách so sánh các ý định đã nhận được đến bộ lọc ý định được cung cấp trong tệp kê khai của các ứng dụng khác trên thiết bị.

Khi khai báo một hoạt động trong tệp kê khai của ứng dụng, bạn có thể đưa vào nếu muốn bộ lọc ý định khai báo khả năng của hoạt động để hoạt động có thể phản hồi ý định từ các ứng dụng khác. Bạn thực hiện việc này bằng cách thêm một phần tử <intent-filter> làm phần tử con của phần tử khai báo của thành phần.

Ví dụ: nếu tạo một ứng dụng email có hoạt động soạn email mới, bạn có thể khai báo bộ lọc ý định để phản hồi lệnh "gửi" ý định gửi một email mới, như trong ví dụ sau:

<manifest ... >
    ...
    <application ... >
        <activity android:name="com.example.project.ComposeEmailActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <data android:type="*/*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Nếu một ứng dụng khác tạo ý định bằng thao tác ACTION_SEND rồi truyền ý định đó đến startActivity(), hệ thống có thể bắt đầu hoạt động của bạn để người dùng có thể soạn thư nháp và gửi .

Để biết thêm thông tin về cách tạo bộ lọc ý định, hãy xem tài liệu về Ý định và bộ lọc ý định.

Khai báo các yêu cầu đối với ứng dụng

Có nhiều thiết bị chạy Android và không phải tất cả thiết bị đều cung cấp tính năng những tính năng và khả năng giống nhau. Để ngăn việc cài đặt ứng dụng của bạn trên các thiết bị thiếu những tính năng mà ứng dụng của bạn cần. Do đó, bạn cần xác định rõ hồ sơ cho loại thiết bị mà ứng dụng của bạn hỗ trợ bằng cách khai báo yêu cầu về thiết bị và phần mềm trong tệp kê khai.

Hầu hết các thông tin khai báo này chỉ nhằm cung cấp thông tin. Hệ thống không đọc các đơn vị quảng cáo đó, nhưng các dịch vụ bên ngoài như Google Play có đọc chúng để cung cấp cơ chế lọc cho người dùng khi họ tìm ứng dụng trên thiết bị của mình.

Ví dụ: giả sử ứng dụng của bạn yêu cầu máy ảnh và sử dụng các API được giới thiệu trong Android 8.0 (API cấp 26). Bạn phải khai báo các yêu cầu này. Giá trị của minSdkVersiontargetSdkVersion được đặt trong tệp build.gradle của mô-đun ứng dụng:

android {
  ...
  defaultConfig {
    ...
    minSdkVersion 26
    targetSdkVersion 29
  }
}

Lưu ý: Đừng đặt minSdkVersiontargetSdkVersion ngay trong tệp kê khai, vì chúng sẽ bị Gradle ghi đè trong quá trình tạo bản dựng. Để biết thêm thông tin, hãy xem Chỉ định các yêu cầu đối với cấp độ API.

Bạn sẽ khai báo tính năng camera trong tệp kê khai của ứng dụng:

<manifest ... >
    <uses-feature android:name="android.hardware.camera.any"
                  android:required="true" />
    ...
</manifest>

Với nội dung khai báo nêu trong những ví dụ này, thiết bị không có hoặc có một ứng dụng Android phiên bản thấp hơn 8.0 không thể cài đặt ứng dụng của bạn qua Google Play. Tuy nhiên, bạn cũng có thể khai báo rằng ứng dụng sử dụng camera nhưng không sử dụng yêu cầu mã đó. Để làm việc này, bạn cần đặt required cho false, hãy kiểm tra trong thời gian chạy thiết bị có máy ảnh và tắt mọi tính năng của máy ảnh nếu cần.

Thông tin khác về cách quản lý khả năng tương thích của ứng dụng với nhiều loại thiết bị có trong bài viết Tổng quan về khả năng tương thích với thiết bị.

Tài nguyên cho ứng dụng

Ứng dụng Android không chỉ gồm mã. Công cụ này cần những tài nguyên tách biệt với mã nguồn (chẳng hạn như hình ảnh, tệp âm thanh và mọi nội dung liên quan đến hình ảnh) bản trình bày ứng dụng. Ví dụ: bạn có thể xác định ảnh động, trình đơn, kiểu, màu sắc và bố cục giao diện người dùng hoạt động bằng các tệp XML.

Dễ dàng sử dụng tài nguyên ứng dụng để cập nhật các đặc điểm khác nhau của ứng dụng mà không cần sửa đổi mã. Cung cấp nhóm tài nguyên thay thế giúp bạn tối ưu hoá ứng dụng cho nhiều loại cấu hình thiết bị, chẳng hạn như các ngôn ngữ và kích thước màn hình khác nhau.

Đối với mỗi tài nguyên bạn đưa vào dự án Android, bộ công cụ xây dựng SDK xác định một giá trị duy nhất số nguyên mà bạn có thể sử dụng để tham chiếu tài nguyên từ mã ứng dụng của bạn hoặc từ các tài nguyên khác được xác định trong XML. Ví dụ: nếu ứng dụng của bạn chứa một tệp hình ảnh có tên logo.png (được lưu trong thư mục res/drawable/), bộ công cụ SDK sẽ tạo mã nhận dạng tài nguyên có tên R.drawable.logo. Mã nhận dạng này liên kết với một số nguyên dành riêng cho ứng dụng, bạn có thể sử dụng để tham chiếu hình ảnh và chèn hình ảnh đó vào giao diện người dùng.

Một trong những khía cạnh quan trọng nhất của việc cung cấp tài nguyên tách biệt với mã nguồn là khả năng cung cấp các tài nguyên thay thế cho các thiết bị khác nhau .

Ví dụ: bằng cách xác định chuỗi giao diện người dùng trong XML, bạn có thể dịch các chuỗi vào ngôn ngữ và lưu các chuỗi đó trong các tệp riêng biệt. Sau đó, Android sẽ áp dụng chuỗi ngôn ngữ thích hợp cho giao diện người dùng dựa trên bộ hạn định ngôn ngữ mà bạn thêm vào tên của thư mục tài nguyên, chẳng hạn như res/values-fr/ cho chuỗi tiếng Pháp giá trị và cài đặt ngôn ngữ của người dùng.

Android hỗ trợ nhiều bộ hạn định cho các tài nguyên thay thế của bạn. Chiến lược phát hành đĩa đơn bộ hạn định là một chuỗi ngắn mà bạn đưa vào tên thư mục tài nguyên để xác định cấu hình thiết bị mà các tài nguyên đó được sử dụng.

Cho Ví dụ: bạn có thể tạo các bố cục khác nhau cho các hoạt động của mình, tuỳ thuộc vào hướng và kích thước màn hình của thiết bị. Khi màn hình thiết bị ở chế độ dọc (cao) bạn có thể muốn bố cục có các nút được sắp xếp theo chiều dọc, nhưng khi màn hình ở hướng ngang (rộng), bạn nên căn chỉnh các nút theo chiều ngang. Để thay đổi bố cục tuỳ thuộc vào hướng, bạn có thể xác định hai bố cục và áp dụng bộ hạn định cho tên thư mục của từng bố cục. Sau đó, hệ thống tự động áp dụng các tuỳ thuộc vào hướng hiện tại của thiết bị.

Để biết thêm thông tin về các loại tài nguyên khác nhau mà bạn có thể đưa vào đơn đăng ký và cách tạo tài nguyên thay thế cho nhiều cấu hình thiết bị, hãy đọc bài viết Tổng quan về tài nguyên ứng dụng. Người nhận tìm hiểu thêm về các phương pháp hay nhất cũng như cách thiết kế các ứng dụng mạnh mẽ và đảm bảo chất lượng phát hành công khai, hãy xem Hướng dẫn về cấu trúc ứng dụng.

Tài nguyên khác

Để tìm hiểu cách phát triển Android qua video và hướng dẫn lập trình, hãy xem Phát triển ứng dụng Android bằng Kotlin Khóa học trên Udacity.

Tiếp tục đọc về:

Ý định và bộ lọc ý định
Tìm hiểu cách sử dụng các API Intent để kích hoạt các thành phần của ứng dụng (chẳng hạn như các hoạt động và dịch vụ) cũng như cách tạo thành phần ứng dụng để các ứng dụng khác sử dụng.
Giới thiệu về hoạt động
Tìm hiểu cách tạo một thực thể của lớp Activity, cung cấp một màn hình riêng biệt trong ứng dụng kèm theo giao diện người dùng.
Tổng quan về tài nguyên ứng dụng
Tìm hiểu cấu trúc của các ứng dụng Android để tách riêng tài nguyên ứng dụng khỏi mã ứng dụng, bao gồm cả cách bạn có thể cung cấp tài nguyên thay thế cho thiết bị cụ thể .

Chủ đề quan tâm:

Tổng quan về khả năng tương thích với thiết bị
Tìm hiểu cách Android hoạt động trên nhiều loại thiết bị và cách bạn có thể tối ưu hoá ứng dụng cho từng thiết bị hoặc hạn chế phạm vi cung cấp ứng dụng cho các thiết bị khác nhau.
Quyền trên Android
Tìm hiểu cách Android chỉ cho phép ứng dụng truy cập vào một số API nhất định hệ thống yêu cầu sự đồng ý của người dùng để ứng dụng của bạn sử dụng các API đó.