Giới thiệu về hoạt động

Lớp Activity là một thành phần quan trọng của ứng dụng Android. Cách thức khởi chạy và kết hợp các hoạt động là một phần cơ bản của mô hình ứng dụng trên nền tảng này. Không giống như các mô hình lập trình mà ứng dụng được khởi chạy bằng phương thức main(), hệ thống Android sẽ bắt đầu mã trong một thực thể Activity bằng cách gọi các phương thức gọi lại cụ thể tương ứng với các giai đoạn cụ thể trong vòng đời của nó.

Tài liệu này giới thiệu khái niệm về các hoạt động, sau đó cung cấp một số hướng dẫn đơn giản về cách làm việc với các hoạt động đó. Để biết thêm thông tin về các phương pháp hay nhất khi xây dựng cấu trúc ứng dụng, vui lòng xem Hướng dẫn về Cấu trúc ứng dụng.

Khái niệm về hoạt động

Trải nghiệm ứng dụng dành cho thiết bị di động khác với trải nghiệm trên máy tính để bàn ở chỗ hoạt động tương tác của người dùng với ứng dụng không phải lúc nào cũng bắt đầu ở cùng một nơi. Thay vào đó, hành trình của người dùng thường bắt đầu một cách không xác định. Ví dụ: nếu mở một ứng dụng email từ màn hình chính, bạn có thể thấy một danh sách email. Ngược lại, nếu đang dùng một ứng dụng mạng xã hội rồi chạy ứng dụng email đó, thì bạn có thể chuyển thẳng đến màn hình của ứng dụng email đó để soạn email.

Lớp Activity được thiết kế để hỗ trợ mô hình này. Khi một ứng dụng gọi một ứng dụng khác, ứng dụng gọi sẽ gọi một hoạt động trong ứng dụng kia, thay vì ứng dụng ở dạng một nguyên tử. Bằng cách này, hoạt động đóng vai trò là điểm truy cập cho hoạt động tương tác của ứng dụng với người dùng. Bạn triển khai một hoạt động làm lớp con của lớp Activity.

Một hoạt động cung cấp một cửa sổ để ứng dụng vẽ giao diện người dùng. Cửa sổ này thường lấp đầy màn hình, nhưng có thể nhỏ hơn màn hình và nổi ở trên các cửa sổ khác. Nhìn chung, một hoạt động triển khai một màn hình trong ứng dụng. Ví dụ: một trong các hoạt động của ứng dụng có thể triển khai màn hình Preferences (Lựa chọn ưu tiên), trong khi một hoạt động khác sẽ triển khai màn hình Select Photo (Chọn ảnh).

Hầu hết ứng dụng đều chứa nhiều màn hình, nghĩa là các ứng dụng đó bao gồm nhiều hoạt động. Thông thường, một hoạt động trong ứng dụng được chỉ định là hoạt động chính, là màn hình đầu tiên xuất hiện khi người dùng khởi chạy ứng dụng. Sau đó, mỗi hoạt động có thể bắt đầu một hoạt động khác để thực hiện các hành động khác nhau. Ví dụ: hoạt động chính trong một ứng dụng email đơn giản có thể cung cấp màn hình hiển thị hộp thư đến email. Từ đó, hoạt động chính có thể khởi chạy các hoạt động khác cung cấp màn hình thực hiện các tác vụ như viết email và mở từng email.

Mặc dù các hoạt động phối hợp cùng nhau để tạo thành trải nghiệm người dùng gắn kết trong một ứng dụng, nhưng mỗi hoạt động chỉ được liên kết lỏng lẻo với các hoạt động khác; thường có rất ít phần phụ thuộc giữa các hoạt động trong một ứng dụng. Trên thực tế, các hoạt động thường khởi động các hoạt động thuộc về ứng dụng khác. Ví dụ: ứng dụng trình duyệt có thể chạy hoạt động Chia sẻ của một ứng dụng mạng xã hội.

Để sử dụng các hoạt động trong ứng dụng, bạn phải đăng ký thông tin về các hoạt động đó trong tệp kê khai của ứng dụng và phải quản lý vòng đời hoạt động một cách phù hợp. Phần còn lại của tài liệu này giới thiệu về những chủ đề đó.

Định cấu hình tệp kê khai

Để ứng dụng của bạn có thể sử dụng các hoạt động, bạn phải khai báo các hoạt động và một số thuộc tính của chúng trong tệp kê khai.

Khai báo hoạt động

Để khai báo hoạt động, hãy mở tệp kê khai và thêm một phần tử <activity> làm phần tử con của phần tử <application>. Ví dụ:

<manifest ... >
  <application ... >
      <activity android:name=".ExampleActivity" />
      ...
  </application ... >
  ...
</manifest >

Thuộc tính bắt buộc duy nhất cho phần tử này là android:name. Thuộc tính này chỉ định tên lớp của hoạt động. Bạn cũng có thể thêm các thuộc tính xác định đặc điểm của hoạt động như nhãn, biểu tượng hoặc giao diện người dùng. Để biết thêm thông tin về các thuộc tính này và các thuộc tính khác, hãy xem tài liệu tham khảo về phần tử <activity>.

Lưu ý: Sau khi phát hành ứng dụng, bạn không nên thay đổi tên của hoạt động. Nếu làm vậy, bạn có thể làm hỏng một số chức năng, chẳng hạn như lối tắt ứng dụng. Để biết thêm thông tin về các thay đổi cần tránh sau khi phát hành, hãy xem phần Những điều không thể thay đổi.

Khai báo bộ lọc ý định

Bộ lọc ý định là một tính năng rất mạnh mẽ của nền tảng Android. Phương thức này cung cấp khả năng khởi chạy một hoạt động không chỉ dựa trên yêu cầu rõ ràng mà còn dựa trên yêu cầu ngầm ẩn. Ví dụ: một yêu cầu rõ ràng có thể yêu cầu hệ thống phải "Bắt đầu hoạt động Gửi email trong ứng dụng Gmail". Ngược lại, yêu cầu ngầm ẩn sẽ yêu cầu hệ thống “Bắt đầu màn hình Gửi email trong bất kỳ hoạt động nào có thể thực hiện công việc đó". Khi giao diện người dùng hệ thống hỏi người dùng sử dụng ứng dụng nào để thực hiện một tác vụ, đó là một bộ lọc ý định đang hoạt động.

Bạn có thể tận dụng tính năng này bằng cách khai báo thuộc tính <intent-filter> trong phần tử <activity>. Phần tử này được định nghĩa bao gồm một phần tử <action> và một phần tử <category> và/hoặc một phần tử <data> (không bắt buộc). Các phần tử này kết hợp để chỉ định loại ý định mà hoạt động của bạn có thể phản hồi. Ví dụ: đoạn mã sau đây cho biết cách định cấu hình một hoạt động gửi dữ liệu văn bản và nhận yêu cầu từ các hoạt động khác để thực hiện việc đó:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>

Trong ví dụ này, phần tử <action> chỉ định rằng hoạt động này gửi dữ liệu. Việc khai báo phần tử <category> dưới dạng DEFAULT sẽ cho phép hoạt động nhận các yêu cầu chạy. Phần tử <data> chỉ định loại dữ liệu mà hoạt động này có thể gửi. Đoạn mã sau đây cho biết cách gọi hoạt động được mô tả ở trên:

Kotlin

val sendIntent = Intent().apply {
    action = Intent.ACTION_SEND
    type = "text/plain"
    putExtra(Intent.EXTRA_TEXT, textMessage)
}
startActivity(sendIntent)

Java

// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
// Start the activity
startActivity(sendIntent);
Nếu dự định ứng dụng của mình sẽ độc lập và không cho phép ứng dụng khác kích hoạt hoạt động của ứng dụng đó, thì bạn không cần bộ lọc ý định nào khác. Các hoạt động mà bạn không muốn cung cấp cho các ứng dụng khác sẽ không có bộ lọc ý định và bạn có thể tự bắt đầu các hoạt động đó bằng cách sử dụng ý định tường minh. Để biết thêm thông tin về cách hoạt động của bạn có thể phản hồi ý định, hãy xem bài viết Ý định và bộ lọc ý định.

Khai báo quyền

Bạn có thể dùng thẻ <activity> của tệp kê khai để kiểm soát ứng dụng nào có thể bắt đầu một hoạt động cụ thể. Hoạt động mẹ không thể chạy hoạt động con trừ phi cả hai hoạt động đều có quyền giống nhau trong tệp kê khai. Nếu bạn khai báo một phần tử <uses-permission> cho một hoạt động mẹ, thì mỗi hoạt động con phải có một phần tử <uses-permission> phù hợp.

Ví dụ: nếu ứng dụng của bạn muốn sử dụng một ứng dụng giả định có tên là SocialApp để chia sẻ một bài đăng lên mạng xã hội, thì chính SocialApp đó phải xác định quyền mà một ứng dụng gọi nó phải có:

<manifest>
<activity android:name="...."
   android:permission=”com.google.socialapp.permission.SHARE_POST”

/>

Sau đó, để được phép gọi SocialApp, ứng dụng của bạn phải khớp với quyền được đặt trong tệp kê khai của SocialApp:

<manifest>
   <uses-permission android:name="com.google.socialapp.permission.SHARE_POST" />
</manifest>

Để biết thêm thông tin về quyền và tính bảo mật nói chung, hãy xem bài viết Tính bảo mật và quyền truy cập.

Quản lý vòng đời hoạt động

Trong suốt vòng đời, một hoạt động sẽ trải qua một số trạng thái. Bạn sử dụng một loạt lệnh gọi lại để xử lý quá trình chuyển đổi giữa các trạng thái. Các phần sau đây giới thiệu về các lệnh gọi lại này.

onCreate()

Bạn phải triển khai lệnh gọi lại này. Lệnh gọi lại này sẽ kích hoạt khi hệ thống tạo hoạt động của bạn. Quá trình triển khai phải khởi chạy các thành phần thiết yếu trong hoạt động của bạn: Ví dụ: ứng dụng của bạn phải tạo các khung hiển thị và liên kết dữ liệu với các danh sách tại đây. Quan trọng nhất, đây là nơi bạn phải gọi setContentView() để xác định bố cục cho giao diện người dùng của hoạt động.

Khi onCreate() kết thúc, lệnh gọi lại tiếp theo luôn là onStart().

onStart()

Khi onCreate() thoát, hoạt động sẽ chuyển sang trạng thái Started (Đã khởi động) và người dùng sẽ nhìn thấy hoạt động này. Lệnh gọi lại này chứa số lượng bước chuẩn bị cuối cùng để hoạt động trở nên nổi bật ở nền trước và có tính tương tác.

onResume()

Hệ thống sẽ gọi lệnh gọi lại này ngay trước khi hoạt động bắt đầu tương tác với người dùng. Tại thời điểm này, hoạt động nằm ở đầu ngăn xếp hoạt động và ghi lại mọi hoạt động đầu vào của người dùng. Hầu hết chức năng cốt lõi của ứng dụng được triển khai trong phương thức onResume().

Lệnh gọi lại onPause() luôn theo sau onResume().

onPause()

Hệ thống sẽ gọi onPause() khi hoạt động mất tiêu điểm và chuyển sang trạng thái Paused (Đã tạm dừng). Chẳng hạn, trạng thái này xảy ra khi người dùng nhấn vào nút Quay lại hoặc Gần đây. Về mặt kỹ thuật, khi hệ thống gọi onPause() cho hoạt động của bạn, thì về mặt kỹ thuật, điều đó có nghĩa là hoạt động của bạn vẫn hiển thị một phần, nhưng thường xuyên nhất là một chỉ báo cho biết người dùng đang rời khỏi hoạt động và hoạt động đó sẽ sớm chuyển sang trạng thái Đã dừng hoặc Tiếp tục.

Một hoạt động ở trạng thái Đã tạm dừng có thể tiếp tục cập nhật giao diện người dùng nếu người dùng muốn cập nhật giao diện người dùng. Ví dụ về hoạt động như vậy: một hoạt động hiển thị màn hình bản đồ điều hướng hoặc trình phát nội dung đa phương tiện đang phát. Ngay cả khi các hoạt động như vậy mất tiêu điểm, người dùng vẫn yêu cầu giao diện người dùng tiếp tục cập nhật.

Bạn không nên sử dụng onPause() để lưu dữ liệu người dùng hoặc ứng dụng, thực hiện lệnh gọi mạng hoặc thực thi các giao dịch cơ sở dữ liệu. Để biết thông tin về cách lưu dữ liệu, hãy xem phần Lưu và khôi phục trạng thái hoạt động.

Sau khi onPause() thực thi xong, lệnh gọi lại tiếp theo sẽ là onStop() hoặc onResume(), tuỳ thuộc vào những gì xảy ra sau khi hoạt động chuyển sang trạng thái Paused (Đã tạm dừng).

onStop()

Hệ thống sẽ gọi onStop() khi hoạt động không còn hiển thị cho người dùng. Điều này có thể xảy ra vì hoạt động bị huỷ bỏ, một hoạt động mới đang bắt đầu hoặc một hoạt động hiện có đang chuyển sang trạng thái Tiếp tục và đang che phủ hoạt động đã dừng. Trong tất cả các trường hợp này, hoạt động đã dừng sẽ không còn hiển thị nữa.

Lệnh gọi lại tiếp theo mà hệ thống gọi sẽ là onRestart(), nếu hoạt động quay lại để tương tác với người dùng hoặc vào onDestroy() nếu hoạt động này hoàn toàn chấm dứt.

onRestart()

Hệ thống sẽ gọi lệnh gọi lại này khi một hoạt động ở trạng thái Paused (Đã dừng) sắp khởi động lại. onRestart() khôi phục trạng thái của hoạt động từ thời điểm hoạt động bị dừng.

Lệnh gọi lại này luôn theo sau là onStart().

onDestroy()

Hệ thống sẽ gọi lệnh gọi lại này trước khi một hoạt động bị huỷ.

Lệnh gọi lại này là lệnh gọi lại cuối cùng mà hoạt động nhận được. onDestroy() thường được triển khai để đảm bảo rằng tất cả tài nguyên của một hoạt động đều được giải phóng khi hoạt động hoặc quy trình chứa hoạt động đó bị huỷ bỏ.

Phần này chỉ giới thiệu về chủ đề này. Để biết thêm thông tin chi tiết về vòng đời hoạt động và các lệnh gọi lại, hãy xem phần Vòng đời hoạt động.