Tác vụ và ngăn xếp lui

Nhiệm vụ là một tập hợp gồm những hoạt động mà người dùng tương tác khi cố gắng làm việc gì đó trong ứng dụng của bạn. Các hoạt động này được sắp xếp trong một ngăn xếp gọi là ngăn xếp lui theo thứ tự mở từng hoạt động.

Ví dụ: một ứng dụng email có thể có một hoạt động để hiển thị danh sách các tin nhắn mới. Khi người dùng chọn một thông báo, một hoạt động mới sẽ mở ra để xem thông báo đó. Hoạt động mới này được thêm vào ngăn xếp lui. Sau đó, khi người dùng nhấn hoặc cử chỉ Quay lại, hoạt động mới đó sẽ kết thúc và được kéo ra khỏi ngăn xếp.

Vòng đời của một tác vụ và ngăn xếp lui

Màn hình chính của thiết bị là nơi bắt đầu cho hầu hết các tác vụ. Khi người dùng chạm vào biểu tượng của một ứng dụng hoặc lối tắt trong trình chạy ứng dụng hoặc trên Màn hình chính, nhiệm vụ của ứng dụng đó sẽ chuyển sang nền trước. Nếu không có tác vụ nào cho ứng dụng, thì một tác vụ mới sẽ được tạo và hoạt động chính của ứng dụng đó sẽ mở ra dưới dạng hoạt động gốc trong ngăn xếp.

Khi hoạt động hiện tại bắt đầu một hoạt động khác, hoạt động mới sẽ được đẩy lên đầu ngăn xếp và lấy làm tâm điểm. Hoạt động trước đó vẫn ở trong ngăn xếp nhưng bị dừng. Khi một hoạt động dừng, hệ thống vẫn giữ nguyên trạng thái hiện tại của giao diện người dùng. Khi người dùng thực hiện thao tác quay lại, hoạt động hiện tại sẽ được đẩy ra từ đầu ngăn xếp và bị huỷ bỏ. Hoạt động trước đó sẽ tiếp tục và trạng thái trước đó của giao diện người dùng sẽ được khôi phục.

Các hoạt động trong ngăn xếp không bao giờ được sắp xếp lại, chỉ được đẩy lên và đẩy ra khỏi ngăn xếp khi chúng được hoạt động hiện tại bắt đầu và bị người dùng loại bỏ thông qua nút Quay lại hoặc cử chỉ. Do đó, ngăn xếp lui hoạt động như một cấu trúc đối tượng vào sau, ra trước. Hình 1 cho thấy một tiến trình với các hoạt động được đẩy lên và đẩy ra từ ngăn xếp lui.

Hình 1. Hình ảnh thể hiện cách mỗi hoạt động mới trong một tác vụ thêm một mục vào ngăn xếp lui. Khi người dùng nhấn hoặc cử chỉ Quay lại, hoạt động hiện tại sẽ bị huỷ và hoạt động trước đó sẽ tiếp tục.

Khi người dùng tiếp tục nhấn hoặc cử chỉ Quay lại, mỗi hoạt động trong ngăn xếp sẽ bật ra để hiển thị hoạt động trước đó, cho đến khi người dùng quay lại Màn hình chính hoặc cho bất kỳ hoạt động nào đang chạy khi tác vụ bắt đầu. Khi tất cả hoạt động bị xoá khỏi ngăn xếp, tác vụ sẽ không còn tồn tại nữa.

Hành vi nhấn lùi cho các hoạt động của trình chạy gốc

Hoạt động của trình chạy gốc là các hoạt động khai báo bộ lọc ý định với cả ACTION_MAINCATEGORY_LAUNCHER. Các hoạt động này là duy nhất vì chúng đóng vai trò là điểm truy cập vào ứng dụng từ trình chạy ứng dụng và được dùng để bắt đầu một tác vụ.

Khi người dùng nhấn hoặc cử chỉ Quay lại từ một hoạt động của trình chạy gốc, hệ thống sẽ xử lý sự kiện này theo cách khác nhau tuỳ thuộc vào phiên bản Android mà thiết bị đang chạy.

Hành vi của hệ thống trên Android 11 trở xuống
Hệ thống sẽ hoàn tất hoạt động này.
Hành vi của hệ thống trên Android 12 trở lên

Hệ thống sẽ chuyển hoạt động và tác vụ của hoạt động sang chế độ nền thay vì hoàn tất hoạt động. Hành vi này khớp với hành vi mặc định của hệ thống khi di chuyển ra khỏi một ứng dụng bằng cử chỉ hoặc nút Màn hình chính.

Trong hầu hết các trường hợp, hành vi này có nghĩa là người dùng có thể nhanh chóng tiếp tục ứng dụng của bạn từ trạng thái nóng, thay vì phải khởi động lại hoàn toàn ứng dụng từ trạng thái nguội.

Nếu cần cung cấp tính năng điều hướng quay lại tuỳ chỉnh, bạn nên sử dụng AndroidX Activity API thay vì ghi đè onBackPressed(). AndroidX Activity API sẽ tự động trì hoãn hành vi phù hợp của hệ thống nếu không có thành phần nào chặn hệ thống Nhấn quay lại.

Tuy nhiên, nếu ứng dụng của bạn ghi đè onBackPressed() để xử lý tính năng Điều hướng quay lại và hoàn tất hoạt động, hãy cập nhật phương thức triển khai để gọi tới super.onBackPressed() thay vì hoàn tất. Khi gọi super.onBackPressed(), hoạt động và tác vụ của hoạt động đó sẽ chuyển sang chế độ nền khi thích hợp và mang lại trải nghiệm thao tác nhất quán hơn cho người dùng trên các ứng dụng.

Thao tác trong nền và nền trước

Hình 2. Hai nhiệm vụ: Nhiệm vụ B nhận hoạt động tương tác của người dùng ở nền trước, còn Nhiệm vụ A ở chế độ nền và đang chờ tiếp tục.

Tác vụ là một đơn vị gắn kết có thể di chuyển tới nền khi người dùng bắt đầu một tác vụ mới hoặc chuyển đến Màn hình chính. Khi ở chế độ nền, mọi hoạt động trong tác vụ sẽ dừng lại, nhưng ngăn xếp lui cho tác vụ vẫn còn nguyên – tác vụ sẽ mất tiêu điểm trong khi một tác vụ khác diễn ra, như trong hình 2. Sau đó, một tác vụ có thể quay lại nền trước để người dùng có thể tiếp tục từ nơi họ đã dừng lại.

Hãy xem xét luồng tác vụ sau đây cho Nhiệm vụ A hiện tại có ba hoạt động trong ngăn xếp, bao gồm 2 hoạt động trong hoạt động hiện tại:

  1. Người dùng sử dụng nút Màn hình chính hoặc cử chỉ, sau đó khởi động một ứng dụng mới từ trình chạy ứng dụng.

    Khi Màn hình chính xuất hiện, Nhiệm vụ A sẽ chuyển sang chế độ nền. Khi ứng dụng mới khởi động, hệ thống sẽ bắt đầu một tác vụ cho ứng dụng đó (Tác vụ B) bằng ngăn xếp hoạt động riêng.

  2. Sau khi tương tác với ứng dụng đó, người dùng sẽ quay lại Màn hình chính một lần nữa và chọn ứng dụng đã bắt đầu Nhiệm vụ A ban đầu.

    Bây giờ, Nhiệm vụ A đã chuyển sang nền trước – cả 3 hoạt động trong ngăn xếp đều nguyên vẹn và hoạt động ở đầu ngăn xếp sẽ tiếp tục. Tại thời điểm này, người dùng cũng có thể chuyển trở lại Nhiệm vụ B bằng cách chuyển đến Màn hình chính và chọn biểu tượng ứng dụng đã bắt đầu tác vụ đó hoặc bằng cách chọn tác vụ của ứng dụng trên màn hình Gần đây.

Nhiều thực thể hoạt động

Hình 3. Hệ thống có thể tạo thực thể cho một hoạt động nhiều lần.

Vì các hoạt động trong ngăn xếp lui không bao giờ được sắp xếp lại, nên nếu ứng dụng của bạn cho phép người dùng bắt đầu một hoạt động cụ thể từ nhiều hoạt động, thì một thực thể mới của hoạt động đó sẽ được tạo và đẩy vào ngăn xếp, thay vì đưa bất kỳ thực thể nào trước đó của hoạt động lên trên cùng. Do đó, một hoạt động trong ứng dụng có thể được tạo thực thể nhiều lần, ngay cả từ các tác vụ khác nhau, như minh hoạ trong hình 3.

Nếu người dùng di chuyển lùi bằng cử chỉ hoặc nút Quay lại, thì các thực thể của hoạt động sẽ hiển thị theo thứ tự mở, mỗi thực thể có trạng thái giao diện người dùng riêng. Tuy nhiên, bạn có thể sửa đổi hành vi này nếu không muốn một hoạt động được tạo thực thể nhiều lần. Hãy tìm hiểu thêm về điều này trong phần quản lý tác vụ.

Môi trường nhiều cửa sổ

Khi các ứng dụng chạy đồng thời trong một môi trường nhiều cửa sổ, được hỗ trợ trong Android 7.0 (API cấp 24) trở lên, hệ thống sẽ quản lý các tác vụ riêng biệt cho từng cửa sổ. Mỗi cửa sổ có thể có nhiều tác vụ. Điều này cũng đúng đối với các ứng dụng Android chạy trên Chromebook: hệ thống quản lý các tác vụ hoặc nhóm tác vụ trên cơ sở từng cửa sổ.

Tóm tắt vòng đời

Tóm tắt hành vi mặc định cho các hoạt động và tác vụ:

  • Khi Hoạt động A khởi chạy Hoạt động B, Hoạt động A sẽ dừng lại nhưng hệ thống vẫn giữ lại trạng thái, chẳng hạn như vị trí cuộn và mọi văn bản được nhập vào biểu mẫu. Nếu người dùng nhấn hoặc sử dụng cử chỉ Quay lại khi đang ở Hoạt động B, thì Hoạt động A sẽ tiếp tục với trạng thái được khôi phục.

  • Khi người dùng rời khỏi một tác vụ bằng cử chỉ hoặc nút Màn hình chính, hoạt động hiện tại sẽ dừng lại và tác vụ của hoạt động đó sẽ chuyển sang chế độ nền. Hệ thống giữ nguyên trạng thái của mọi hoạt động trong tác vụ. Nếu sau đó người dùng tiếp tục nhiệm vụ bằng cách chọn biểu tượng trình chạy đã bắt đầu nhiệm vụ, thì nhiệm vụ đó sẽ xuất hiện ở nền trước và tiếp tục hoạt động ở đầu ngăn xếp.

  • Nếu người dùng nhấn hoặc cử chỉ Quay lại, thì hoạt động hiện tại sẽ được kéo ra khỏi ngăn xếp và bị huỷ bỏ. Hoạt động trước đó trong ngăn xếp sẽ tiếp tục. Khi một hoạt động bị huỷ bỏ, hệ thống sẽ không giữ lại trạng thái của hoạt động đó.

    Hành vi này khác với các hoạt động của trình chạy gốc khi ứng dụng đang chạy trên thiết bị chạy Android 12 trở lên.

  • Hệ thống có thể tạo thực thể cho hoạt động nhiều lần, ngay cả từ các tác vụ khác.

Quản lý công việc

Android quản lý các nhiệm vụ và ngăn xếp lui bằng cách xếp tất cả các hoạt động bắt đầu liên tiếp vào cùng một nhiệm vụ, theo thứ tự vào sau cùng, ra trước. Cách này hiệu quả với hầu hết ứng dụng và bạn thường không phải lo lắng về cách hoạt động của mình liên kết với các tác vụ hoặc cách chúng tồn tại trong ngăn xếp lui.

Tuy nhiên, bạn có thể quyết định rằng mình muốn làm gián đoạn hoạt động bình thường. Ví dụ: có thể bạn muốn một hoạt động trong ứng dụng của mình bắt đầu một tác vụ mới khi nó bắt đầu, thay vì được đặt trong tác vụ hiện tại. Hoặc khi bắt đầu một hoạt động, bạn có thể muốn chuyển đến một thực thể hiện có của hoạt động đó thay vì tạo một thực thể mới ở đầu ngăn xếp lui. Hoặc bạn có thể muốn ngăn xếp lui bị xoá mọi hoạt động, ngoại trừ hoạt động gốc khi người dùng rời khỏi tác vụ.

Bạn có thể thực hiện những việc này và nhiều thao tác khác bằng cách sử dụng các thuộc tính trong phần tử tệp kê khai <activity> và gắn cờ trong ý định mà bạn truyền đến startActivity().

Dưới đây là các thuộc tính <activity> chính mà bạn có thể dùng để quản lý công việc:

Và đây là những cờ ý định chính mà bạn có thể sử dụng:

Những phần sau thảo luận cách sử dụng các thuộc tính tệp kê khai và cờ ý định này để xác định cách hoạt động liên kết với tác vụ cũng như hành vi của hoạt động trong ngăn xếp lui.

Ngoài ra, còn có những điểm cần cân nhắc về cách trình bày và quản lý các tác vụ và hoạt động trên màn hình Gần đây. Thông thường, bạn để hệ thống xác định cách thể hiện tác vụ và hoạt động của mình trên màn hình Gần đây và bạn không cần sửa đổi hành vi này. Để biết thêm thông tin, hãy xem bài viết Màn hình Gần đây.

Xác định chế độ chạy

Các chế độ chạy cho phép bạn xác định cách liên kết một thực thể mới của hoạt động với tác vụ hiện tại. Bạn có thể xác định các chế độ chạy theo 2 cách, như được mô tả trong các phần sau:

  • Sử dụng tệp kê khai

    Khi khai báo một hoạt động trong tệp kê khai, bạn có thể chỉ định cách hoạt động đó liên kết với các tác vụ khi nó bắt đầu.

  • Sử dụng cờ ý định

    Khi gọi startActivity(), bạn có thể đưa một cờ vào Intent để khai báo cách thức (hoặc liệu) hoạt động mới có liên kết với tác vụ hiện tại hay không.

Vì vậy, nếu Hoạt động A khởi chạy Hoạt động B, thì Hoạt động B có thể xác định trong tệp kê khai cách nó liên kết với tác vụ hiện tại và Hoạt động A có thể sử dụng cờ ý định để yêu cầu cách Hoạt động B có thể liên kết với tác vụ hiện tại.

Nếu cả hai hoạt động đều xác định cách Hoạt động B liên kết với một tác vụ, thì yêu cầu của Hoạt động A (như xác định trong ý định) sẽ được ưu tiên áp dụng thay cho yêu cầu của Hoạt động B, như được xác định trong tệp kê khai.

Xác định chế độ chạy bằng tệp kê khai

Khi khai báo một hoạt động trong tệp kê khai, bạn có thể chỉ định cách hoạt động liên kết với một tác vụ bằng cách sử dụng thuộc tính launchMode của phần tử <activity>.

Bạn có thể chỉ định 5 chế độ chạy cho thuộc tính launchMode:

  1. "standard"
    Chế độ mặc định. Hệ thống sẽ tạo một thực thể mới của hoạt động trong tác vụ mà hoạt động đó bắt đầu và chuyển ý định đến đó. Hệ thống có thể tạo thực thể cho hoạt động nhiều lần, mỗi thực thể có thể thuộc về các tác vụ khác nhau và một tác vụ có thể có nhiều thực thể.
  2. "singleTop"
    Nếu một thực thể của hoạt động đã tồn tại ở đầu tác vụ hiện tại, hệ thống sẽ chuyển ý định đến thực thể đó thông qua lệnh gọi phương thức onNewIntent(), thay vì tạo một thực thể mới của hoạt động. Hoạt động được tạo thực thể nhiều lần, mỗi thực thể có thể thuộc về các tác vụ khác nhau và một tác vụ có thể có nhiều thực thể (nhưng chỉ khi hoạt động ở đầu ngăn xếp lui không phải là thực thể hiện có của hoạt động).

    Ví dụ: giả sử ngăn xếp lui của một tác vụ bao gồm hoạt động gốc A với các hoạt động B, C và D ở trên cùng (vì vậy, ngăn xếp là A-B-C-D, với D ở trên cùng). Một ý định đến một hoạt động thuộc loại D. Nếu D có chế độ chạy "standard" mặc định, thì một thực thể mới của lớp sẽ được khởi chạy và ngăn xếp trở thành A-B-C-D-D. Tuy nhiên, nếu chế độ chạy của D là "singleTop", thì thực thể hiện có của D sẽ nhận được ý định thông qua onNewIntent() vì ý định này nằm ở đầu ngăn xếp và ngăn xếp vẫn là A-B-C-D. Mặt khác, nếu có ý định đến cho một hoạt động thuộc loại B, thì một thực thể mới của B sẽ được thêm vào ngăn xếp ngay cả khi chế độ chạy của hoạt động đó là "singleTop".

  3. "singleTask"
    Hệ thống tạo hoạt động vào thư mục gốc của một tác vụ mới hoặc định vị hoạt động trong một tác vụ hiện có bằng cùng một đối tượng tương đồng. Nếu đã có một thực thể của hoạt động, hệ thống sẽ chuyển ý định đến thực thể hiện có thông qua lệnh gọi phương thức onNewIntent(), thay vì tạo một thực thể mới. Trong khi đó, tất cả các hoạt động khác ở trên đó đều bị huỷ bỏ.
  4. "singleInstance".
    Hành vi tương tự như đối với "singleTask", ngoại trừ việc hệ thống không chạy bất kỳ hoạt động nào khác trong tác vụ đang giữ thực thể đó. Hoạt động luôn là thành phần đơn nhất và duy nhất trong tác vụ của nó. Mọi hoạt động do hoạt động này bắt đầu sẽ mở trong một tác vụ riêng.
  5. "singleInstancePerTask".
    Hoạt động chỉ có thể chạy dưới dạng hoạt động gốc của tác vụ (hoạt động đầu tiên đã tạo tác vụ) và do đó chỉ có thể có một thực thể duy nhất của hoạt động này trong tác vụ. Khác với chế độ chạy singleTask, hoạt động này có thể được bắt đầu ở nhiều thực thể trong các tác vụ khác nhau nếu bạn đặt cờ FLAG_ACTIVITY_MULTIPLE_TASK hoặc FLAG_ACTIVITY_NEW_DOCUMENT.

Một ví dụ khác: ứng dụng Trình duyệt Android khai báo rằng hoạt động của trình duyệt web luôn mở trong tác vụ riêng bằng cách chỉ định chế độ chạy singleTask trong phần tử <activity>. Điều này có nghĩa là nếu ứng dụng của bạn đưa ra ý định mở Trình duyệt Android, thì hoạt động của ứng dụng đó sẽ không được đặt vào cùng một tác vụ với ứng dụng. Thay vào đó, một tác vụ mới sẽ bắt đầu cho Trình duyệt hoặc nếu Trình duyệt đã có một tác vụ chạy trong nền, thì tác vụ đó sẽ được đưa lên để xử lý ý định mới.

Bất kể một hoạt động bắt đầu trong một tác vụ mới hay trong cùng một tác vụ với hoạt động đã bắt đầu hoạt động đó, thì cử chỉ và nút Quay lại luôn đưa người dùng đến hoạt động trước đó. Tuy nhiên, nếu bạn bắt đầu một hoạt động chỉ định chế độ chạy singleTask và một thực thể của hoạt động đó tồn tại trong tác vụ trong nền, thì toàn bộ tác vụ đó sẽ được đưa lên nền trước. Tại thời điểm này, ngăn xếp lui bao gồm tất cả hoạt động từ tác vụ được đưa lên ở đầu ngăn xếp. Hình 4 cho thấy loại tình huống này.

Hình 4. Hình ảnh minh hoạ cách thêm một hoạt động có chế độ chạy "singleTask" vào ngăn xếp lui. Nếu hoạt động đã là một phần của tác vụ trong nền có ngăn xếp lui riêng, thì toàn bộ ngăn xếp lui đó cũng sẽ xuất hiện ở đầu tác vụ hiện tại.

Để biết thêm thông tin về cách sử dụng các chế độ chạy trong tệp kê khai, hãy xem tài liệu về phần tử <activity>.

Xác định các chế độ chạy bằng cờ Ý định

Khi bắt đầu một hoạt động, bạn có thể sửa đổi mối liên kết mặc định của một hoạt động với tác vụ của hoạt động đó bằng cách đưa cờ vào ý định mà bạn gửi đến startActivity(). Những cờ mà bạn có thể sử dụng để sửa đổi hành vi mặc định là:

FLAG_ACTIVITY_NEW_TASK

Hệ thống sẽ bắt đầu hoạt động trong một tác vụ mới. Nếu một tác vụ đang chạy cho hoạt động đang được bắt đầu, thì tác vụ đó sẽ được đưa lên nền trước với trạng thái gần đây nhất được khôi phục và hoạt động sẽ nhận được ý định mới trong onNewIntent().

Điều này tạo ra hành vi tương tự như giá trị "singleTask" launchMode đã thảo luận trong phần trước.

FLAG_ACTIVITY_SINGLE_TOP

Nếu hoạt động đang được bắt đầu là hoạt động hiện tại, ở đầu ngăn xếp lui, thì thực thể hiện có sẽ nhận được lệnh gọi đến onNewIntent() thay vì tạo một thực thể mới của hoạt động.

Điều này tạo ra hành vi tương tự như giá trị "singleTop" launchMode đã thảo luận trong phần trước.

FLAG_ACTIVITY_CLEAR_TOP

Nếu hoạt động đang được bắt đầu đã chạy trong tác vụ hiện tại, thì thay vì chạy một thực thể mới của hoạt động đó, hệ thống sẽ huỷ tất cả các hoạt động khác ở trên hoạt động đó. Ý định được phân phối đến thực thể đã tiếp tục của hoạt động, nay ở trên cùng, thông qua onNewIntent().

Không có giá trị nào cho thuộc tính launchMode tạo ra hành vi này.

FLAG_ACTIVITY_CLEAR_TOP thường được dùng cùng với FLAG_ACTIVITY_NEW_TASK. Khi được sử dụng cùng nhau, các cờ này sẽ xác định một hoạt động hiện có trong một tác vụ khác và đặt hoạt động đó vào vị trí có thể phản hồi ý định.

Xử lý đối tượng chung sở thích

Đối tượng chung sở thích cho biết công việc mà một hoạt động "ưu tiên" thuộc về. Theo mặc định, tất cả hoạt động từ cùng một ứng dụng có đối tượng tương đồng với nhau: chúng "ưu tiên" ở trong cùng một tác vụ.

Tuy nhiên, bạn có thể sửa đổi đối tượng chung sở thích mặc định cho một hoạt động. Các hoạt động được xác định trong các ứng dụng khác nhau có thể có chung đối tượng tương đồng và các hoạt động được xác định trong cùng một ứng dụng có thể được chỉ định đối tượng chung sở thích tác vụ khác nhau.

Bạn có thể sửa đổi đối tượng tương đồng của một hoạt động bằng cách sử dụng thuộc tính taskAffinity của phần tử <activity>.

Thuộc tính taskAffinity nhận một giá trị chuỗi phải khác với tên gói mặc định được khai báo trong phần tử <manifest> vì hệ thống sử dụng tên đó để xác định đối tượng tương đồng của tác vụ mặc định cho ứng dụng.

Đối tượng tương đồng này có hiệu lực trong hai trường hợp:

  1. Khi ý định chạy một hoạt động chứa cờ FLAG_ACTIVITY_NEW_TASK.

    Theo mặc định, một hoạt động mới sẽ được chạy trong tác vụ của hoạt động có tên là startActivity(). Phương thức này được đẩy vào cùng ngăn xếp lui với phương thức gọi.

    Tuy nhiên, nếu ý định được truyền đến startActivity() chứa cờ FLAG_ACTIVITY_NEW_TASK, hệ thống sẽ tìm một tác vụ khác để chứa hoạt động mới. Thông thường, đây là một tác vụ mới. Tuy nhiên, bạn không nhất thiết phải làm như vậy. Nếu hiện có một tác vụ hiện có cùng đối tượng tương đồng với hoạt động mới, thì hoạt động đó sẽ được chạy trong tác vụ đó. Nếu không, quá trình này sẽ bắt đầu một nhiệm vụ mới.

    Nếu cờ này khiến một hoạt động bắt đầu một tác vụ mới và người dùng sử dụng nút Màn hình chính hoặc cử chỉ để rời khỏi tác vụ đó, thì phải có cách nào đó để người dùng quay lại tác vụ đó. Một số thực thể (chẳng hạn như trình quản lý thông báo) luôn bắt đầu các hoạt động trong một tác vụ bên ngoài chứ không phải là một phần của riêng chúng. Vì vậy, chúng luôn đặt FLAG_ACTIVITY_NEW_TASK trong ý định chúng chuyển đến startActivity().

    Nếu một thực thể bên ngoài có thể sử dụng cờ này có thể gọi hoạt động của bạn, hãy chú ý rằng người dùng có một cách độc lập để quay lại tác vụ đã bắt đầu, chẳng hạn như với biểu tượng trình chạy, trong đó hoạt động gốc của tác vụ có bộ lọc ý định CATEGORY_LAUNCHER. Để biết thêm thông tin, hãy xem phần cách bắt đầu việc cần làm.

  2. Khi một hoạt động đặt thuộc tính allowTaskReparenting thành "true".

    Trong trường hợp này, hoạt động có thể di chuyển từ tác vụ mà nó bắt đầu sang tác vụ có đối tượng tương đồng khi tác vụ đó xuất hiện ở nền trước.

    Ví dụ: giả sử một hoạt động báo cáo điều kiện thời tiết ở các thành phố đã chọn được xác định là một phần của ứng dụng du lịch. Hoạt động này có cùng đối tượng tương đồng với các hoạt động khác trong cùng một ứng dụng (đối tượng chung sở thích mặc định của ứng dụng) và có thể được gán lại về cấp độ gốc bằng thuộc tính này.

    Khi một trong các hoạt động của bạn bắt đầu hoạt động của trình báo cáo thời tiết, ban đầu hoạt động đó thuộc về cùng một tác vụ với hoạt động của bạn. Tuy nhiên, khi tác vụ của ứng dụng du lịch xuất hiện ở nền trước, hoạt động của trình báo cáo thời tiết sẽ được giao lại cho tác vụ đó và hiển thị trong hoạt động đó.

Xoá ngăn xếp lui

Nếu người dùng rời khỏi một tác vụ trong thời gian dài, thì hệ thống sẽ xoá tác vụ đó của tất cả hoạt động, ngoại trừ hoạt động gốc. Khi người dùng quay lại tác vụ, chỉ hoạt động gốc được khôi phục. Hệ thống hoạt động theo cách này dựa trên giả định rằng sau một khoảng thời gian dài, người dùng đã bỏ những việc họ đang làm trước đó và quay lại nhiệm vụ để bắt đầu một việc gì đó mới.

Bạn có thể sử dụng một số thuộc tính hoạt động để sửa đổi hành vi này:

alwaysRetainTaskState
Khi thuộc tính này được đặt thành "true" trong hoạt động gốc của một tác vụ, hành vi mặc định vừa mô tả sẽ không xảy ra. Tác vụ này giữ lại tất cả hoạt động trong ngăn xếp ngay cả sau một thời gian dài.
clearTaskOnLaunch

Khi thuộc tính này được đặt thành "true" trong hoạt động gốc của một tác vụ, tác vụ sẽ bị xoá khỏi hoạt động gốc bất cứ khi nào người dùng rời khỏi tác vụ và quay lại tác vụ đó. Nói cách khác, hàm này trái ngược với alwaysRetainTaskState. Người dùng luôn quay lại tác vụ ở trạng thái ban đầu, ngay cả sau khi chỉ rời khỏi tác vụ đó một lúc.

finishOnTaskLaunch

Thuộc tính này giống như clearTaskOnLaunch, nhưng hoạt động trên một hoạt động duy nhất chứ không phải toàn bộ tác vụ. Thuộc tính này cũng có thể khiến mọi hoạt động hoàn tất, ngoại trừ hoạt động gốc. Khi bạn đặt chính sách này thành "true", hoạt động vẫn chỉ là một phần của tác vụ trong phiên hiện tại. Nếu người dùng rời khỏi rồi quay lại tác vụ, thì tác vụ đó sẽ không xuất hiện nữa.

Bắt đầu việc cần làm

Bạn có thể thiết lập hoạt động làm điểm truy cập cho một tác vụ bằng cách cung cấp cho tác vụ đó một bộ lọc ý định với "android.intent.action.MAIN" là hành động được chỉ định và "android.intent.category.LAUNCHER" là danh mục được chỉ định:

<activity ... >
    <intent-filter ... >
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    ...
</activity>

Bộ lọc ý định thuộc loại này sẽ khiến biểu tượng và nhãn cho hoạt động hiển thị trong trình chạy ứng dụng, cung cấp cho người dùng một cách để chạy hoạt động và quay lại tác vụ mà hoạt động tạo ra bất cứ lúc nào sau khi hoạt động đó khởi chạy.

Khả năng thứ hai này rất quan trọng. Người dùng phải rời khỏi một tác vụ rồi quay lại sau đó bằng trình chạy hoạt động này. Vì lý do này, chỉ sử dụng 2 chế độ chạy đánh dấu các hoạt động là luôn khởi tạo một tác vụ, "singleTask""singleInstance", khi hoạt động có bộ lọc ACTION_MAINCATEGORY_LAUNCHER.

Ví dụ: hãy tưởng tượng điều gì có thể xảy ra nếu thiếu bộ lọc: một ý định khởi chạy hoạt động "singleTask", bắt đầu một tác vụ mới và người dùng dành một khoảng thời gian để làm việc trong tác vụ đó. Sau đó, người dùng sẽ sử dụng nút Màn hình chính hoặc cử chỉ. Việc cần làm hiện đã được chuyển ở chế độ nền và không hiển thị. Lúc này, người dùng không có cách nào để quay lại tác vụ vì thao tác này không được thể hiện trong trình chạy ứng dụng.

Đối với những trường hợp bạn không muốn người dùng có thể quay lại một hoạt động, hãy đặt finishOnTaskLaunch của phần tử <activity> thành "true". Để biết thêm thông tin, hãy xem phần xoá ngăn xếp lui.

Bạn có thể tìm thêm thông tin về cách trình bày cũng như quản lý các tác vụ và hoạt động trên màn hình Gần đây trên màn hình Gần đây.

Tài nguyên khác