+11

LaunchMode trong Android

I. Task

Trước khi đi vào tìm hiểu launchMode thì chúng ta sẽ đi qua khái niệm Task:
Task là tập hợp gồm nhiều activity mà người dùng tương tác với ứng dụng khi thực hiện một công việc nhất định. Các activity được sắp xếp trong một stack (được gọi là Back stack), theo thứ tự mở của mỗi activity.

II. LaunchMode

Có 4 launchMode khác nhau mà bạn có thể sử dụng: standard, singleTop, singleTask, singleInstance. Tùy vào mục đích sử dụng như là tạo mới hay sử dụng lại activity đã có trước đó mà bạn sẽ sử dụng launchMode sao cho phù hợp.

Sử dụng launchMode

Khi bạn khai báo một activity trong file AndroidManifest.xml, bạn có thể chỉ định cách activity sẽ liên kết với các task như nào khi nó được khởi chạy.
Ví dụ:

<activity android:name=".Activity_A" android:launchMode="standard">

Sử dụng Intent Flags

Ngoài việc khai báo launchMode trong AndroidManifest.xml thì bạn có thể sử dụng Intent Flags khi startActivity().
Ví dụ:

Intent intent = new Intent(Activity_A.this, Activity_A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

Chúng ta sẽ cùng tìm hiểu cụ thể từng launchMode nhé.

1. Standard (Mặc định)

Đây là chế độ mặc định. Ở standard, khi activity được khởi tạo, activity mới sẽ được đặt lên đỉnh của stack trong cùng 1 task.

Ví dụ:

Giả sử mình có 4 activity đều được khai báo là standard: Activity_A, Activity_B, Activity_C, Activity_D.

Ví dụ 1 Ví dụ 2
Khi mình start B, C, D, A từ A thì trong cùng 1 task của mình đang có 5 activities. Vậy nếu mình tiếp tục start A thì sao? Khi đó trong cùng 1 task của mình đang có 6 activities.
- Thứ tự được xếp vào stack sẽ là:
A (Base) -> B -> C -> D -> A (Top).
- Khi đó số lượng Instance của A: 2
- Thứ tự được xếp vào stack sẽ là:
A (Base) -> B -> C -> D -> A -> A (Top).
- Khi đó số lượng Instance của A: 3


Thông qua ví dụ trên, chắc bạn đã hiểu cơ chế hoạt động của standard như nào rồi đúng không ạ? Thực chất chỉ là việc xếp chồng các activity vào stack trong cùng 1 task bất kể nó đã tồn tại Instance trước đó hay chưa.
Một số bạn sẽ thắc mắc là tại sao mình nói là chỉ có 1 task mà trong hình ví dụ ở trên lại ghi task là 2. Thì ngay sau khi app của chúng ta được run thì hệ thống đã có 1 root task rồi nhé.

2. SingleTop

Cơ chế hoạt động của singleTop khá là giống với standard. Tuy nhiên, ở singleTop nếu tồn tại 1 Instance của activity cùng loại ở đỉnh của stack. Nó sẽ không tạo activity mới, hệ thống sẽ đưa Intent tới Instance qua lời gọi tới phương thức onNewIntent() .

Ví dụ:
Giả sử mình có 1 activity được khai báo là singleTop: Activity_A
và 3 activity được khai báo là standard: Activity_B, Activity_C, Activity_D.

Ví dụ 1 Ví dụ 2
Khi mình start B, B, C, D, A từ A thì trong cùng 1 task của mình đang có 6 activities. Vậy nếu mình tiếp tục start A thì sao? Khi đó trong cùng 1 task của mình đang có 6 activities.
- Thứ tự được xếp vào stack sẽ là:
A (Base) -> B -> B -> C -> D -> A (Top).
- Khi đó số lượng Instance của A: 2
- Thứ tự được xếp vào stack giữ nguyên là:
A (Base) -> B -> B -> C -> D -> A (Top).
- Khi đó số lượng Instance của A: 2

3. SingleTask

  • Mỗi activity chỉ có 1 Instance tại một thời điểm, nếu activity đã tồn tại Instance thì task chứa activity đó sẽ được đẩy lên đầu, và Instance sẽ được gọi thông qua onNewIntent(). Nếu chưa tồn tại Instance nào của Activity thì một task mới sẽ được tạo ra để chứa nó.
  • Nếu trong cùng 1 task, khi gọi đến Instance của activity khai báo singleTask thì tất cả các activity đặt trên nó ở trong stack sẽ bị xóa đi.

Tuy nhiên, trong thực tế singleTask sẽ không hoạt động như vậy. Và để singleTask hoạt động đúng như mô tả thì bạn cần gán thêm thuộc tính taskAffinity (đầu vào là một string định nghĩa Affinity name).

<activity android:name=".Activity_B" android:launchMode="singleTask"
   android:taskAffinity=""/>

Mặc định thì các activity trong 1 application có cùng affinity của root activity (package name)

Ví dụ:
Giả sử mình có 1 activity được khai báo là singleTop: Activity_A,
1 activity được khai báo là singleTask: Activity_B
và 2 activity được khai báo là standard: Activity_C, Activity_D.

  • Trường hợp khôngtaskAffinity:
Ví dụ 1 Ví dụ 2
Khi mình start B, C, D, A từ A thì trong cùng 1 task của mình đang có 5 activities. Vậy mình sẽ tiếp tục start B thì sao?Khi đó trong cùng 1 task của mình đang có 2 activities
- Thứ tự được xếp vào stack sẽ là:
A (Base) -> B -> C -> D -> A (Top).
- Khi đó:
+ số lượng task: 1
+ số lượng Instance của A: 2
+ số lượng instance của B: 1
- Thứ tự được xếp vào stack sẽ là:
A (Base) -> B (Top).
- Khi đó:
+ số lượng task: 1
+ số lượng Instance của A: 1
+ số lượng instance của B: 1
  • Trường hợp taskAffinity:
Ví dụ 1 Ví dụ 2
Khi mình start B, C, D, A từ A Vậy mình sẽ tiếp tục start B thì sao?
- Thứ tự được xếp vào stack sẽ là:
+ Task 1: A (Base-Top)
+ Task 2: B (Base) -> C -> D -> A (Top).
- Khi đó:
+ số lượng task: 2
+ số lượng Instance của A: 2
+ số lượng instance của B: 1
- Thứ tự được xếp vào stack sẽ là:
+ Task 1: A (Base-Top)
+ Task 2: B (Base-Top)
- Khi đó:
+ số lượng task: 2
+ số lượng Instance của A: 1
+ số lượng instance của B: 1

4. SingleInstance

Khá là giống với singleTask, ngoại trừ việc hệ thống sẽ không đưa thêm bất kì activity nào vào task đang giữ Instance của activity đó. Tức là mỗi task chỉ có thể có duy nhất một activity. Nếu bất kì activity nào khác được khởi tạo thì nó sẽ được khởi tạo ở task khác.

Ví dụ:
Giả sử mình có 2 activity được khai báo là singleInstance: Activity_A, Activity_C
1 activity được khai báo là singleTask: Activity_B
và 1 activity được khai báo là standard: Activity_D.

  • Trường hợp khôngtaskAffinity:
Ví dụ 1 Ví dụ 2
Khi mình start B, C, A từ A Tiếp tục start D, A thì sao? Khi đó D sẽ được tạo từ B
- Thứ tự được xếp vào stack sẽ là:
+ Task 1 (Task Id 43): A (Base-Top)
+ Task 2 (Task Id 46): B (Base-Top)
+ Task 3 (Task Id 45): C (Base-Top)
- Khi đó:
+ số lượng task: 3
+ số lượng Instance của A: 1
+ số lượng instance của C: 1
- Thứ tự được xếp vào stack sẽ là:
+ Task 1 (Task Id 43): A (Base-Top)
+ Task 2 (Task Id 46): B (Base) -> D (Top)
+ Task 3 (Task Id 45): C (Base-Top)
- Khi đó:
+ số lượng task: 3
+ số lượng Instance của A: 1
+ số lượng instance của C: 1


Ở ví dụ trên bạn có thể thấy có 3 task nhưng chỉ hiện duy nhất 1 task trong Task Manager. Để giải quyết vấn đề trên thì chúng ta sẽ sử dụng taskAffinity tương tự với singleTask đã nêu ở phần trên.

III. Kết luận

Trên đây là một số kiến thức mà mình tổng hợp được, mình hi vọng thông qua đó mà các bạn có thể hiểu được cơ chế hoạt động của launchMode để có thể linh hoạt trong thiết kế và điều hướng activity sao cho phù hợp với ứng dụng. Mình rất mong nhận được góp ý từ bạn đọc. Xin cảm ơn.

Tài liệu tham khảo:


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí