Kiến thức cơ bản lập trình Android cần biết

Kiến thức cơ bản lập trình Android cần biết

Ứng dụng Android được viết bằng ngôn ngữ lập trình Java/Kotlin/C++. Bộ công cụ phát triển SDK được Google cung cấp sẽ biên dịch mã nguồn của bạn thành ứng dụng cho máy Android. Tất các các mã nguồn, tài nguyên tĩnh (image, âm thanh, vector…), cùng với bất kỳ tập tin dữ liệu sẽ được đóng gói thành 1 file APK. File APK này là một tập tin chứa tất cả các nội dung cần thiết của một ứng dụng Android. Các thiết bị dựa trên nền tảng Android đọc các chỉ thị trong tập tin APK này để cài đặt và chạy ứng dụng được phân phối.

Sau khi được cài đặt lên một thiết bị, từng ứng dụng Android sẽ được cô lập trong một vùng nhớ dành riêng cho nó. Vùng nhớ này được gọi là sandbox – hộp cát ứng dụng.

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

Bằng cách này, hệ thống Android triển khai nguyên tắc đặc quyền ít nhất. Cụ thể, theo mặc định, mỗi ứng dụng chỉ có thể truy cập vào các thành phần mà nó cần để thực hiện công việc của mình và không hơn. Điều này tạo ra một môi trường rất bảo mật mà trong đó một ứng dụng không thể truy cập các bộ phận của hệ thống mà nó không được cấp quyền.

Tuy nhiên, có nhiều cách để một ứng dụng chia sẻ dữ liệu với các ứng dụng khác và để 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 ID người dùng Linux, trong trường hợp đó chúng có thể truy cập các tệp của nhau. Để tiết kiệm tài nguyên của hệ thống, các ứng dụng có cùng ID người dùng cũng có thể sắp xếp để chạy trong cùng tiến trình Linux và chia sẻ cùng VM (các ứng dụng cũng phải được ký bằng cùng chứng chỉ).
  • Một ứng dụng có thể yêu cầu quyền truy cập dữ liệu của thiết bị chẳng hạn như danh bạ của người dùng, tin nhắn SMS, thiết bị lưu trữ gắn được (thẻ SD), máy ảnh, Bluetooth và nhiều nữa. Tất cả quyền ứng dụng đều phải được cấp bởi người dùng tại thời điểm cài đặt.

Đó là nội dung cơ bản về cách mà một ứng dụng Android tồn tại trong hệ thống. Phần còn lại của tài liệu này giới thiệu với bạn về:

  • Các thành phần khuôn khổ cốt lõi định nghĩa ứng dụng của bạn.
  • Tệp bản kê khai mà trong đó bạn khai báo các thành phần và tính năng yêu cầu của thiết bị cho ứng dụng của bạn.
  • Các tài nguyên tách riêng với mã ứng dụng và cho phép ứng dụng của bạn tối ưu hóa hành vi của nó cho nhiều loại cấu hình thiết bị đa dạng.

Thành phần của Ứng dụng

Thành phần của ứng dụng là những khối dựng thiết yếu của một ứng dụng Android. Mỗi thành phần là một điểm khác nhau mà qua đó hệ thống có thể vào ứng dụng của bạn. Không phải tất cả thành phần đều là các điểm nhập thực tế cho người dùng và một số phụ thuộc vào nhau, nhưng mỗi thành phần tồn tại như một thực thể riêng và đóng một vai trò riêng—mỗi thành phần là một khối dựng duy nhất giúp định nghĩa hành vi chung của ứng dụng của bạn.

Có bốn loại thành phần ứng dụng khác nhau. Mỗi loại có một mục đích riêng và có một vòng đời riêng, xác định cách thành phần được tạo lập và hủy.

Sau đây là bốn loại thành phần ứng dụng:

Activity – Hoạt Động

Một activity biểu diễn một màn hình đơn với một giao diện người dùng. Ví dụ, một ứng dụng e-mail có thể có một hoạt động với chức năng hiển thị một danh sách e-mail mới, một hoạt động khác để soạn e-mail, và một hoạt động khác để đọc e-mail. Mặc dù các hoạt động cùng nhau tạo thành một trải nghiệm người dùng gắn kết trong ứng dụng e-mail, mỗi hoạt động lại độc lập với nhau. Như vậy, một ứng dụng khác có thể khởi động bất kỳ hoạt động nào trong số này (nếu ứng dụng e-mail cho phép nó). Ví dụ, một ứng dụng máy ảnh có thể khởi động hoạt động trong ứng dụng e-mail có chức năng soạn thư mới, để người dùng chia sẻ một bức ảnh.

Hoạt động được triển khai như một lớp con của Activity và bạn có thể tìm hiểu thêm về nó trong hướng dẫn dành cho nhà phát triển tại đây.

Service – Dịch Vụ

Một dịch vụ là một thành phần chạy ngầm để thực hiện các thao tác chạy lâu hoặc để thực hiện công việc cho các tiến trình từ xa. Dịch vụ không cung cấp giao diện người dùng. Ví dụ, một dịch vụ có thể phát nhạc dưới nền trong khi người dùng đang ở một ứng dụng khác, hoặc nó có thể tải dữ liệu qua mạng mà không chặn người dùng tương tác với hoạt động. Một thành phần khác, chẳng hạn như một hoạt động, có thể khởi động dịch vụ và để nó chạy hoặc gắn kết với nó để tương tác với nó.

Dịch vụ được triển khai như một lớp con của Service và bạn có thể tìm hiểu thêm về nó trong hướng dẫn cho nhà phát triển tại đây.

Content Provider – Trình cung cấp nội dung

Một trình cung cấp nội dung sẽ quản lý một tập dữ liệu ứng dụng được chia sẻ. Bạn có thể lưu trữ dữ liệu trong hệ thống tệp, một cơ sở dữ liệu SQLite, trên web, hay bất kỳ vị trí lưu trữ liên tục nào khác mà ứng dụng của bạn 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 hay thậm chí sửa đổi dữ liệu (nếu trình cung cấp nội dung cho phép). Ví dụ, hệ thống Android cung cấp một trình cung cấp nội dung có chức năng quản lý thông tin danh bạ của người dùng. Như vậy, bất kỳ ứng dụng nào có các quyền phù hợp đều có thể truy vấn bất kỳ phần nào của trình cung cấp nội dung (chẳng hạn như ContactsContract.Data) để đọc và ghi thông tin về một người cụ thể.

Trình cung cấp nội dung cũng hữu ích với việc đọc và ghi dữ liệu riêng tư đối với ứng dụng của bạn và không được chia sẻ. Ví dụ, ứng dụng mẫu Note Pad sử dụng một trình cung cấp nội dung để lưu các ghi chú.

Trình cung cấp nội dung được triển khai như một lớp con của ContentProvider và phải triển khai một tập các API tiêu chuẩn cho phép các ứng dụng khác thực hiện giao tác. Để biết thêm thông tin, xem hướng dẫn cho nhà phát triển tại đây.

Boardcast Receiver – Hàm nhận quảng bá

Một hàm nhận quảng bá (broadcast receiver) là một thành phần có chức năng hồi đáp lại các thông báo quảng bá trên toàn hệ thống. Nhiều quảng bá khởi nguồn từ hệ thống—ví dụ, một quảng bá thông báo rằng màn hình đã tắt, pin yếu, hoặc một bức ảnh được chụp. Các ứng dụng cũng có thể khởi tạo quảng bá—ví dụ như để các ứng dụng khác biết rằng một phần dữ liệu đã được tải xuống thiết bị và có sẵn để họ sử dụng. Mặc dù các hàm nhận quảng bá không hiển thị giao diện người dùng, chúng có thể tạo một thông báo thanh trạng thái để cảnh báo người tiếp nhận khi xảy ra một sự kiện quảng bá. Tuy nhiên trường hợp phổ biến hơn đó là hàm nhận quảng bá chỉ là một “cổng kết nối” tới các thành phần khác và nhằm mục đích thực hiện lượng công việc rất ít. Ví dụ, nó có thể khởi tạo một dịch vụ để thực hiện một số công việc dựa trên sự kiện.

Hàm nhận quảng bá được triển khai như một lớp con của BroadcastReceiver và mỗi quảng bá được chuyển giao như một đối tượng Intent. Để biết thêm thông tin, hãy xem tại đây.

Tóm lại:

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

Khi hệ thống khởi động một thành phần, nó sẽ khởi động tiến trình cho ứng dụng đó (nếu tiến trình không đang chạy) và khởi tạo các lớp cần thiết cho thành phần. Ví dụ, nếu ứng dụng của bạn khởi động hoạt động trong ứng dụng máy ảnh có chức năng chụp ảnh, hoạt động đó sẽ chạy trong tiến trình thuộc về ứng dụng máy ảnh chứ không chạy trong tiến trình của ứng dụng của bạn. Vì thế, khô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 điểm nhập duy nhất (ví dụ, không có chức năng main()).

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

Bài sau →