Hỗ trợ chế độ nhiều cửa sổ

Chế độ nhiều cửa sổ cho phép các ứng dụng đồng thời chia sẻ cùng một màn hình. Hệ thống có thể hiển thị 2 ứng dụng cạnh nhau hoặc một ứng dụng phía trên một ứng dụng khác (chế độ chia đôi màn hình), một ứng dụng trong một cửa sổ nhỏ chồng lên các ứng dụng khác (chế độ hình trong hình) hoặc từng ứng dụng trong các cửa sổ có thể thay đổi kích thước và di chuyển riêng biệt (chế độ cửa sổ trên máy tính).

Hình 1. Hiển thị 2 ứng dụng cạnh nhau trong chế độ chia đôi màn hình.

Để xem hướng dẫn cho người dùng về cách truy cập chế độ chia đôi màn hình trên điện thoại, hãy chuyển đến phần Xem 2 ứng dụng cùng một lúc trên điện thoại Pixel.

Các tính năng nhiều cửa sổ dành riêng cho từng phiên bản

Trải nghiệm người dùng ở chế độ nhiều cửa sổ phụ thuộc vào phiên bản Android và loại thiết bị:

  • Android 7.0 (API cấp 24) ra mắt chế độ chia đôi màn hình trên các thiết bị màn hình nhỏ và chế độ hình trong hình trên một số thiết bị.

    • Chế độ chia đôi màn hình sẽ bố trí 2 ứng dụng để phủ đầy màn hình. 2 ứng dụng đó có thể xuất hiện cạnh nhau hoặc một ứng dụng ở phía trên ứng dụng kia. Người dùng có thể kéo đường phân chia ngăn cách hai ứng dụng để phóng to một ứng dụng và thu nhỏ ứng dụng còn lại.

    • Chế độ hình trong hình cho phép người dùng tiếp tục phát video trong khi tương tác với một ứng dụng khác (xem phần Hỗ trợ chế độ hình trong hình).

    • Nhà sản xuất thiết bị màn hình lớn có thể bật chế độ cửa sổ trên máy tính. Trong chế độ này, người dùng có thể tuỳ ý thay đổi kích thước của từng hoạt động.

      Bạn có thể định cấu hình ứng dụng để xử lý chế độ nhiều cửa sổ bằng cách chỉ định kích thước tối thiểu được cho phép đối với hoạt động. Bạn cũng có thể tắt chế độ nhiều cửa sổ cho ứng dụng bằng cách đặt resizeableActivity="false" để đảm bảo hệ thống luôn hiện ứng dụng ở chế độ toàn màn hình.

  • Android 8.0 (API cấp 26) hỗ trợ cả chế độ hình trong hình trên các thiết bị màn hình nhỏ.

  • Android 12 (API cấp 31) biến chế độ nhiều cửa sổ thành chế độ tiêu chuẩn.

    • Trên màn hình lớn (lớp kích thước cửa sổ trung bình hoặc mở rộng), nền tảng này hỗ trợ chế độ nhiều cửa sổ đối với tất cả các ứng dụng, bất kể cấu hình ứng dụng là gì. Nếu là resizeableActivity="false", ứng dụng sẽ được đưa vào chế độ tương thích khi cần thiết để phù hợp với kích thước màn hình.

    • Trên màn hình nhỏ (lớp kích thước cửa sổ thu gọn), hệ thống sẽ kiểm tra minWidthminHeight của một hoạt động để xác định xem hoạt động đó có thể chạy ở chế độ nhiều cửa sổ hay không. Nếu resizeableActivity="false", ứng dụng sẽ không thể chạy ở chế độ nhiều cửa sổ, bất kể chiều rộng và chiều cao tối thiểu.

  • Android 16 (API cấp 36) ghi đè các hạn chế về hướng màn hình, tỷ lệ khung hình và khả năng thay đổi kích thước.

Chế độ chia đôi màn hình

Người dùng kích hoạt chế độ chia đôi màn hình bằng cách làm như sau:

  1. Mở màn hình Gần đây
  2. Vuốt một ứng dụng vào chế độ xem
  3. Nhấn vào biểu tượng ứng dụng trên thanh tiêu đề của ứng dụng
  4. Chọn tuỳ chọn trình đơn chia đôi màn hình
  5. Chọn một ứng dụng khác trên màn hình Gần đây hoặc đóng màn hình này rồi chạy một ứng dụng khác

Người dùng thoát khỏi chế độ chia đôi màn hình bằng cách kéo bộ chia cửa sổ vào cạnh của màn hình – lên hoặc xuống, sang trái hoặc sang phải.

Mở cửa sổ chia đôi màn hình liền kề

Nếu ứng dụng của bạn cần truy cập vào nội dung thông qua một ý định, bạn có thể dùng FLAG_ACTIVITY_LAUNCH_ADJACENT để mở nội dung trong một cửa sổ chia đôi màn hình liền kề.

FLAG_ACTIVITY_LAUNCH_ADJACENT được giới thiệu trong Android 7.0 (API cấp 24) để cho phép các ứng dụng chạy ở chế độ chia đôi màn hình khởi chạy các hoạt động trong cửa sổ liền kề.

Android 12L (API cấp 32) trở lên đã mở rộng định nghĩa của cờ để cho phép các ứng dụng chạy ở chế độ toàn màn hình kích hoạt chế độ chia đôi màn hình rồi khởi chạy các hoạt động trong cửa sổ liền kề.

Để khởi chạy một hoạt động liền kề, hãy dùng FLAG_ACTIVITY_LAUNCH_ADJACENT kết hợp với FLAG_ACTIVITY_NEW_TASK, chẳng hạn như:

fun openUrlInAdjacentWindow(url: String) {
    Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url)
       addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT or Intent.FLAG_ACTIVITY_NEW_TASK)
    }.also { intent -> startActivity(intent) }
}

Vòng đời của hoạt động ở chế độ nhiều cửa sổ

Chế độ nhiều cửa sổ không thay đổi vòng đời hoạt động. Tuy nhiên, trạng thái tiếp tục của ứng dụng trong chế độ nhiều cửa sổ sẽ thay đổi theo các phiên bản Android khác nhau.

Tiếp tục nhiều lần (multi-resume)

Android 10 (API cấp 29) và các phiên bản cao hơn hỗ trợ tính năng tiếp tục nhiều lần – tất cả các hoạt động vẫn ở trạng thái RESUMED khi thiết bị ở chế độ nhiều cửa sổ. Một hoạt động có thể bị tạm dừng nếu một hoạt động minh bạch nằm trên hoạt động đó hoặc khi không thể lấy hoạt động đó làm tâm điểm, chẳng hạn như hoạt động đó ở chế độ hình trong hình. Cũng có thể không có hoạt động nào lấy được tiêu điểm tại một thời gian nhất định, chẳng hạn như lúc ngăn thông báo đang mở. Phương thức onStop() hoạt động như thường lệ: phương thức này được gọi bất cứ khi nào một hoạt động bị đưa ra khỏi màn hình.

Tính năng Tiếp tục nhiều lần cũng hoạt động trên một số thiết bị chạy Android 9 (API cấp 28). Để chọn sử dụng tính năng Tiếp tục nhiều lần trên các thiết bị Android 9, hãy thêm siêu dữ liệu của tệp kê khai sau:

<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" />

Để xác minh một thiết bị nào đó có hỗ trợ siêu dữ liệu của tệp kê khai này, hãy tham khảo thông số kỹ thuật của thiết bị.

Android 9

Ở chế độ nhiều cửa sổ trên Android 9 (API cấp 28) trở xuống, chỉ có hoạt động mà người dùng tương tác gần đây nhất mới ở trạng thái hoạt động tại một thời điểm nhất định. Hoạt động này được xem là trên cùng và là hoạt động duy nhất ở trạng thái RESUMED. Mọi hoạt động có thể quan sát khác là STARTED nhưng không phải là RESUMED. Tuy nhiên, các hoạt động có thể quan sát nhưng không tiếp tục có mức độ ưu tiên đối với hệ thống cao hơn các hoạt động không thể quan sát. Nếu người dùng tương tác với một trong các hoạt động hiển thị, thì hoạt động đó sẽ được tiếp tục và hoạt động ở trên cùng trước đó sẽ chuyển sang trạng thái STARTED.

Khi có nhiều hoạt động trong một quá trình hoạt động đơn lẻ của ứng dụng, hoạt động có thứ tự z cao nhất sẽ được tiếp tục và các hoạt động khác bị tạm dừng.

Các thay đổi về cấu hình

Khi người dùng đặt một ứng dụng vào chế độ nhiều cửa sổ, hệ thống sẽ thông báo cho hoạt động về sự thay đổi cấu hình như được chỉ định trong phần Xử lý các thay đổi về cấu hình. Điều này cũng xảy ra khi người dùng đổi kích thước ứng dụng hoặc đưa ứng dụng trở về chế độ toàn màn hình.

Về cơ bản, thay đổi này có cùng tác động đến vòng đời hoạt động như khi hệ thống thông báo cho ứng dụng rằng thiết bị đã chuyển từ hướng dọc sang hướng ngang, ngoại trừ việc các thứ nguyên ứng dụng được thay đổi thay vì chỉ được hoán đổi. Hoạt động của bạn có thể tự xử lý thay đổi về cấu hình hoặc ứng dụng của bạn có thể cho phép hệ thống huỷ hoạt động và tạo lại hoạt động đó với các kích thước mới.

Nếu người dùng đổi kích thước một cửa sổ và làm cho cửa sổ đó lớn hơn theo một trong hai thứ nguyên, thì hệ thống sẽ đổi kích thước hoạt động cho phù hợp với thao tác của người dùng, cũng như đưa ra sự thay đổi về cấu hình khi cần thiết. Nếu ứng dụng bị chậm trễ trong quá trình vẽ ở các vùng mới xuất hiện, hệ thống sẽ tạm thời tô màu các vùng đó bằng màu sắc được chỉ định bởi thuộc tính windowBackground hoặc theo thuộc tính kiểu dáng mặc định windowBackgroundFallback.

Quyền truy cập tài nguyên độc quyền

Để hỗ trợ tính năng tiếp tục nhiều lần, hãy sử dụng phương thức gọi lại trong vòng đời onTopResumedActivityChanged().

Lệnh gọi lại được gọi khi một hoạt động nhận được hoặc mất đi vị trí hoạt động tiếp tục hàng đầu. Điều này rất quan trọng khi một hoạt động sử dụng tài nguyên singleton dùng chung, chẳng hạn như micrô hoặc camera:

override fun onTopResumedActivityChanged(topResumed: Boolean) {
    if (topResumed) {
        // Top resumed activity.
        // Can be a signal to re-acquire exclusive resources.
    } else {
        // No longer the top resumed activity.
    }
}

Lưu ý rằng ứng dụng có thể mất đi tài nguyên vì các lý do khác, chẳng hạn như việc xoá bỏ một phần cứng được chia sẻ.

Trong mọi trường hợp, một ứng dụng phải xử lý linh hoạt các sự kiện và những thay đổi về trạng thái có ảnh hưởng đến các tài nguyên có sẵn.

Đối với các ứng dụng sử dụng máy ảnh, CameraManager.AvailabilityCallback#onCameraAccessPrioritiesChanged() sẽ cung cấp gợi ý rằng có thể đây là thời điểm thích hợp để thử truy cập vào máy ảnh. Phương thức này có trên Android 10 (API cấp 29).

Hãy nhớ rằng resizeableActivity=false không đảm bảo quyền truy cập độc quyền vào máy ảnh vì các ứng dụng khác sử dụng máy ảnh có thể được mở trên các màn hình khác.

Hình 2. Máy ảnh ở chế độ nhiều cửa sổ.

Ứng dụng của bạn không cần phải giải phóng máy ảnh khi bị mất tâm điểm. Chẳng hạn, bạn có thể muốn tiếp tục xem trước camera trong khi người dùng tương tác với ứng dụng được tiếp tục trên cùng được chọn làm tâm điểm mới nhất. Sẽ không có vấn đề gì nếu ứng dụng của bạn tiếp tục chạy camera khi không phải là ứng dụng trên cùng được tiếp tục, nhưng bạn phải xử lý đúng cách trường hợp ngắt kết nối. Khi ứng dụng được tiếp tục trên cùng muốn sử dụng camera, ứng dụng đó có thể mở camera và ứng dụng của bạn sẽ mất quyền truy cập. Ứng dụng của bạn có thể mở lại camera khi lấy lại tâm điểm.

Sau khi một ứng dụng nhận được lệnh gọi lại CameraDevice.StateCallback#onDisconnected(), các lệnh gọi tiếp theo trên máy ảnh của thiết bị sẽ gửi một CameraAccessException.

Chỉ số cửa sổ

Android 11 (API cấp 30) đã ra mắt các phương thức WindowManager sau đây để cung cấp các giới hạn của những ứng dụng chạy ở chế độ nhiều cửa sổ:

Các phương thức computeCurrentWindowMetrics()computeMaximumWindowMetrics() trong thư viện Jetpack WindowManager cung cấp chức năng tương tự riêng biệt nhưng có khả năng tương thích ngược với API cấp 14.

Để lấy chỉ số của các màn hình khác với màn hình hiện tại, hãy làm như sau (như minh hoạ trong đoạn mã):

  • Tạo một ngữ cảnh hiển thị
  • Tạo ngữ cảnh cửa sổ cho màn hình
  • Nhận WindowManager của ngữ cảnh cửa sổ
  • Nhận WindowMetrics khu vực hiển thị tối đa có sẵn cho ứng dụng

val windowMetrics = context.createDisplayContext(display)
                           .createWindowContext(WindowManager.LayoutParams.TYPE_APPLICATION, null)
                           .getSystemService(WindowManager::class.java)
                           .maximumWindowMetrics

Các phương thức ngừng hoạt động

Các phương thức Display getSize()getMetrics() đã ngừng hoạt động trong API cấp 30 để nhường chỗ cho các phương thức WindowManager mới.

Android 12 (API cấp 31) ngừng sử dụng các phương thức Display getRealSize()getRealMetrics(), đồng thời cập nhật hành vi của các phương thức này cho phù hợp hơn với hành vi của getMaximumWindowMetrics().

Cấu hình chế độ nhiều cửa sổ

Nếu ứng dụng của bạn nhắm đến Android 7.0 (API cấp 24) trở lên, thì bạn có thể định cấu hình việc các hoạt động của ứng dụng có hỗ trợ chế độ nhiều cửa sổ hay không và hỗ trợ bằng cách nào. Bạn có thể thiết lập các thuộc tính trong tệp kê khai để kiểm soát cả kích thước và bố cục. Chế độ cài đặt thuộc tính của một hoạt động gốc sẽ áp dụng cho tất cả các hoạt động trong ngăn xếp tác vụ. Ví dụ: nếu hoạt động gốc có android:resizeableActivity="true", thì tất cả hoạt động trong ngăn xếp tác vụ đều có thể thay đổi kích thước. Trên một số thiết bị lớn hơn, chẳng hạn như Chromebook, ứng dụng của bạn có thể chạy trong một cửa sổ có thể thay đổi kích thước ngay cả khi bạn chỉ định android:resizeableActivity="false". Nếu điều này có thể dẫn đến sự cố ứng dụng, bạn có thể sử dụng bộ lọc trên Google Play để hạn chế việc cung cấp ứng dụng trên các thiết bị như vậy.

Android 12 (API cấp 31) mặc định ở chế độ nhiều cửa sổ. Trên màn hình lớn (lớp kích thước cửa sổ trung bình hoặc mở rộng), tất cả ứng dụng đều chạy ở chế độ nhiều cửa sổ bất kể cấu hình ứng dụng là gì. Trên các màn hình nhỏ, hệ thống sẽ kiểm tra chế độ cài đặt minWidth, minHeightresizeableActivity của một hoạt động để xác định xem hoạt động đó có thể chạy ở chế độ nhiều cửa sổ hay không.

resizeableActivity

Thiết lập thuộc tính này trong phần tử <activity> hoặc <application> của tệp kê khai để bật hoặc tắt chế độ nhiều cửa sổ đối với API cấp 30 trở xuống:

<application
  android:name=".MyActivity"
  android:resizeableActivity=["true" | "false"] />;

Nếu bạn đặt thuộc tính này thành true, thì hoạt động có thể được khởi chạy ở chế độ chia đôi màn hình và chế độ cửa sổ trên máy tính. Nếu bạn thiết lập thuộc tính này thành false, hoạt động này sẽ không hỗ trợ chế độ nhiều cửa sổ. Nếu giá trị là false và người dùng cố gắng chạy hoạt động ở chế độ nhiều cửa sổ, thì hoạt động đó sẽ chiếm toàn màn hình.

Nếu ứng dụng của bạn nhắm đến API cấp 24 trở lên, nhưng bạn không chỉ định giá trị cho thuộc tính này, thì giá trị đó sẽ mặc định là true.

Nếu ứng dụng của bạn nhắm đến API cấp 31 trở lên, thì thuộc tính này sẽ hoạt động theo cách khác nhau trên màn hình nhỏ và màn hình lớn:

  • Màn hình lớn (lớp kích thước cửa sổ trung bình hoặc mở rộng): Tất cả ứng dụng đều hỗ trợ chế độ nhiều cửa sổ. Thuộc tính này cho biết liệu một hoạt động có thể đổi kích thước hay không. Nếu là resizeableActivity="false", ứng dụng sẽ được đưa vào chế độ tương thích khi cần thiết để phù hợp với kích thước màn hình.
  • Màn hình nhỏ (loại kích thước cửa sổ nhỏ gọn): Nếu resizeableActivity="true" và chiều rộng tối thiểu cũng như chiều cao tối thiểu của hoạt động đáp ứng yêu cầu của chế độ nhiều cửa sổ, thì hoạt động sẽ hỗ trợ chế độ nhiều cửa sổ. Nếu resizeableActivity="false", thì hoạt động sẽ không hỗ trợ chế độ nhiều cửa sổ, bất kể chiều rộng và chiều cao tối thiểu của hoạt động.

Nếu ứng dụng của bạn nhắm đến API cấp 36 trở lên, thì thuộc tính này sẽ bị bỏ qua trên những màn hình có chiều rộng nhỏ nhất >= 600 dp. Tuy nhiên, ứng dụng hoàn toàn tôn trọng lựa chọn tỷ lệ khung hình của người dùng (xem phần Các chế độ ghi đè của người dùng cho mỗi ứng dụng).

Nếu bạn đang tạo một trò chơi, hãy xem phần Hướng, tỷ lệ khung hình và khả năng thay đổi kích thước của ứng dụng để tìm hiểu cách loại trừ trò chơi của bạn khỏi các thay đổi trên Android 16 (API cấp 36).

supportsPictureInPicture

Đặt thuộc tính này trong nút <activity> của tệp kê khai để cho biết liệu hoạt động có hỗ trợ chế độ hình trong hình hay không.

<activity
  android:name=".MyActivity"
  android:supportsPictureInPicture=["true" | "false"] />

configChanges

Để tự xử lý các thay đổi về cấu hình ở chế độ nhiều cửa sổ, chẳng hạn như khi người dùng đổi kích thước một cửa sổ, hãy thêm thuộc tính android:configChanges vào nút <activity> trong tệp kê khai ứng dụng với ít nhất là các giá trị sau:

<activity
  android:name=".MyActivity"
  android:configChanges="screenSize | smallestScreenSize
      | screenLayout | orientation" />

Sau khi thêm android:configChanges, hoạt động và các mảnh của bạn sẽ nhận được lệnh gọi lại đến onConfigurationChanged() thay vì bị huỷ và tạo lại. Sau đó, bạn có thể cập nhật các khung hiển thị, tải lại tài nguyên và thực hiện các thao tác khác nếu cần.

<layout>

Trên Android 7.0 (API cấp 24) trở lên, phần tử tệp kê khai <layout> hỗ trợ một số thuộc tính ảnh hưởng đến hành vi của một hoạt động ở chế độ nhiều cửa sổ:

  • android:defaultHeight, android:defaultWidth: Chiều cao và chiều rộng mặc định của hoạt động khi khởi chạy ở chế độ cửa sổ trên máy tính.

  • android:gravity: Vị trí ban đầu của hoạt động khi khởi chạy ở chế độ cửa sổ trên máy tính. Hãy xem lớp Gravity để biết các giá trị phù hợp.

  • android:minHeight, android:minWidth: Chiều cao tối thiểu và chiều rộng tối thiểu cho hoạt động ở cả chế độ chia đôi màn hình và chế độ cửa sổ trên máy tính. Nếu người dùng di chuyển đường phân chia ở chế độ chia đôi màn hình để làm cho một hoạt động trở nên nhỏ hơn mức tối thiểu đã chỉ định, thì hệ thống sẽ cắt hoạt động theo kích thước mà người dùng yêu cầu.

Đoạn mã sau đây cho biết cách chỉ định kích thước và vị trí mặc định của hoạt động cũng như kích thước tối thiểu của hoạt động đó khi được hiển thị ở chế độ cửa sổ trên máy tính:

<activity android:name=".MyActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end|..."
          android:minHeight="450dp"
          android:minWidth="300dp" />
</activity>

Chế độ nhiều cửa sổ trong thời gian chạy

Kể từ Android 7.0, hệ thống sẽ cung cấp chức năng hỗ trợ những ứng dụng có thể chạy ở chế độ nhiều cửa sổ.

Các tính năng bị tắt trong chế độ nhiều cửa sổ

Ở chế độ nhiều cửa sổ, Android có thể tắt hoặc bỏ qua các tính năng không áp dụng được cho hoạt động đang chia sẻ màn hình thiết bị với các hoạt động hoặc ứng dụng khác.

Ngoài ra, một số tuỳ chọn tuỳ chỉnh Giao diện người dùng hệ thống bị tắt. Ví dụ: các ứng dụng không thể ẩn thanh trạng thái nếu đang chạy ở chế độ nhiều cửa sổ (xem phần Kiểm soát chế độ hiển thị giao diện người dùng hệ thống).

Hệ thống sẽ bỏ qua các thay đổi đối với thuộc tính android:screenOrientation.

Các truy vấn và lệnh gọi lại của chế độ nhiều cửa sổ

Lớp Activity cung cấp các phương thức sau để hỗ trợ chế độ nhiều cửa sổ:

  • isInMultiWindowMode(): Cho biết liệu hoạt động có ở chế độ nhiều cửa sổ hay không.

  • isInPictureInPictureMode(): Cho biết liệu hoạt động có ở chế độ hình trong hình hay không.

  • onMultiWindowModeChanged(): Hệ thống gọi phương thức này mỗi khi hoạt động chuyển vào hoặc thoát khỏi chế độ nhiều cửa sổ. Hệ thống sẽ chuyển cho phương thức này một giá trị là true nếu hoạt động đang chuyển vào chế độ nhiều cửa sổ hoặc false nếu hoạt động đang thoát khỏi chế độ nhiều cửa sổ.

  • onPictureInPictureModeChanged(): Hệ thống sẽ gọi phương thức này bất cứ khi nào hoạt động chuyển vào hoặc thoát khỏi chế độ hình trong hình. Hệ thống sẽ chuyển vào phương thức này một giá trị là true nếu hoạt động chuyển vào chế độ hình trong hình hoặc false nếu hoạt động đó thoát khỏi chế độ hình trong hình.

Lớp Fragment sẽ hiển thị các phiên bản của nhiều phương thức trong số sau; chẳng hạn, Fragment.onMultiWindowModeChanged().

Chế độ Hình trong hình

Để đặt một hoạt động vào chế độ hình trong hình, hãy gọi enterPictureInPictureMode() Phương thức này không có hiệu lực nếu thiết bị không hỗ trợ chế độ hình trong hình. Để biết thêm thông tin, hãy xem bài viết Thêm video bằng tính năng hình trong hình (PiP).

Hoạt động mới ở chế độ nhiều cửa sổ

Khi khởi chạy một hoạt động mới, bạn có thể cho biết rằng hoạt động mới sẽ được hiển thị bên cạnh hoạt động hiện tại nếu có thể. Sử dụng cờ ý định FLAG_ACTIVITY_LAUNCH_ADJACENT để yêu cầu hệ thống cố gắng tạo hoạt động mới trong một cửa sổ liền kề, vì vậy hai hoạt động đó sẽ chia sẻ màn hình. Hệ thống sẽ cố gắng hết sức để thực hiện điều này, nhưng không đảm bảo sẽ xảy ra.

Nếu thiết bị ở chế độ cửa sổ trên máy tính và bạn đang khởi chạy một hoạt động mới, bạn có thể chỉ định các thứ nguyên và vị trí màn hình của hoạt động mới bằng cách gọi ActivityOptions.setLaunchBounds(). Phương thức này không có hiệu lực nếu thiết bị không ở chế độ nhiều cửa sổ.

Trên API cấp 30 trở xuống, nếu bạn khởi chạy một hoạt động trong ngăn xếp tác vụ, hoạt động đó sẽ thay thế hoạt động trên màn hình, kế thừa tất cả các thuộc tính nhiều cửa sổ của hoạt động đó. Nếu muốn khởi chạy hoạt động mới dưới dạng một cửa sổ riêng biệt ở chế độ nhiều cửa sổ, thì bạn phải khởi chạy hoạt động đó trong ngăn xếp tác vụ mới.

Android 12 (API cấp 31) cho phép các ứng dụng phân tách một cửa sổ thao tác của ứng dụng thành nhiều hoạt động. Bạn có thể xác định cách ứng dụng hiển thị các hoạt động (toàn màn hình, cạnh nhau hoặc xếp chồng lên nhau) bằng cách tạo một tệp cấu hình XML hoặc thực hiện các lệnh gọi API WindowManager của Jetpack.

Kéo và thả

Người dùng có thể kéo và thả dữ liệu từ một hoạt động sang một hoạt động khác trong khi hai hoạt động đang chia sẻ màn hình. (Trước Android 7.0, người dùng chỉ có thể kéo và thả dữ liệu trong một hoạt động đơn lẻ). Để nhanh chóng thêm tính năng hỗ trợ cho việc chấp nhận nội dung bị thả, hãy xem API DropHelper. Để được hướng dẫn đầy đủ về thao tác kéo và thả, hãy xem bài viết Bật tính năng kéo và thả.

Nhiều phiên bản

Mỗi hoạt động gốc có một tác vụ riêng, xuất hiện trong cửa sổ riêng. Để khởi chạy một phiên bản mới của ứng dụng trong một cửa sổ riêng biệt, hãy bắt đầu các hoạt động mới bằng cờ FLAG_ACTIVITY_NEW_TASK. Bạn có thể kết hợp chế độ cài đặt này với thuộc tính nhiều cửa sổ để yêu cầu một vị trí cụ thể cho cửa sổ mới. Ví dụ: một ứng dụng mua sắm có thể hiển thị nhiều cửa sổ liền kề để so sánh các sản phẩm.

Android 12 (API cấp 31) trở lên cho phép bạn khởi chạy song song 2 phiên bản của một hoạt động trong cùng một cửa sổ tác vụ trong tính năng nhúng hoạt động.

Nếu bạn muốn cho phép người dùng bắt đầu một phiên bản khác của ứng dụng từ trình chạy ứng dụng hoặc thanh tác vụ, hãy đặt android:resizeableActivity="true" trong tệp kê khai hoạt động của trình chạy và không dùng chế độ chạy ngăn nhiều phiên bản. Ví dụ: hệ thống có thể tạo thực thể cho một hoạt động singleInstancePerTask nhiều lần trong các tác vụ khác nhau khi FLAG_ACTIVITY_MULTIPLE_TASK hoặc FLAG_ACTIVITY_NEW_DOCUMENT được đặt.

Trên Android 15 (API cấp 35) trở lên, PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI cho phép bạn khai báo khả năng hỗ trợ nhiều phiên bản. Thuộc tính này là một tín hiệu rõ ràng để giao diện người dùng hệ thống hiển thị các chế độ kiểm soát cho người dùng nhằm tạo nhiều phiên bản của ứng dụng. Thuộc tính này độc lập với chế độ chạy nhưng chỉ nên được dùng khi chế độ chạy cho một hoạt động hoặc ứng dụng tương thích với thuộc tính này, chẳng hạn như khi chế độ chạy không phải là singleInstance.

Khi nhiều phiên bản của một ứng dụng đang chạy trong các cửa sổ riêng biệt trên một thiết bị có thể gập lại, một hoặc nhiều phiên bản có thể được gửi tới nền nếu tư thế của thiết bị thay đổi. Ví dụ: giả sử một thiết bị được mở ra và có hai thực thể ứng dụng đang chạy trong các cửa sổ riêng biệt ở mỗi bên nếp gấp màn hình. Khi thiết bị gập lại, một trong các thực thể đó có thể bị chấm dứt thay vì cố gắng điều chỉnh các cửa sổ cho cả hai phiên bản trên màn hình nhỏ hơn.

Xác minh chế độ nhiều cửa sổ

Dù có nhắm đến API cấp 24 trở lên hay không, bạn cũng nên xác minh cách hoạt động của ứng dụng ở chế độ nhiều cửa sổ trong trường hợp người dùng cố gắng chạy ứng dụng đó ở chế độ nhiều cửa sổ trên thiết bị Android 7.0 trở lên.

Kiểm tra thiết bị

Các thiết bị chạy Android 7.0 (API cấp 24) trở lên có hỗ trợ chế độ nhiều cửa sổ.

API cấp 23 trở xuống

Khi người dùng cố gắng sử dụng ứng dụng ở chế độ nhiều cửa sổ, hệ thống sẽ buộc đổi kích thước ứng dụng, trừ khi ứng dụng khai báo một hướng cố định.

Nếu ứng dụng của bạn không khai báo một hướng cố định, bạn nên khởi chạy ứng dụng trên thiết bị chạy Android 7.0 trở lên và cố gắng đặt ứng dụng ở chế độ chia đôi màn hình. Xác minh rằng người dùng có trải nghiệm có thể chấp nhận được khi ứng dụng bị buộc đổi kích thước.

Nếu ứng dụng khai báo một hướng cố định, bạn nên tìm cách đặt ứng dụng ở chế độ nhiều cửa sổ. Xác minh rằng khi bạn làm như vậy thì ứng dụng sẽ ở chế độ toàn màn hình.

API cấp 24 đến 30

Nếu ứng dụng của bạn nhắm đến các API cấp 24 đến 30 và không tắt tính năng hỗ trợ chế độ nhiều cửa sổ, hãy xác minh hành vi sau đây ở cả chế độ chia đôi màn hình và chế độ cửa sổ trên máy tính:

  • Khởi chạy ứng dụng ở chế độ toàn màn hình, sau đó chuyển sang chế độ nhiều cửa sổ bằng cách nhấn và giữ nút Gần đây. Xác minh rằng ứng dụng chuyển đúng cách.

  • Khởi chạy ứng dụng trực tiếp ở chế độ nhiều cửa sổ và xác minh rằng ứng dụng khởi chạy đúng cách. Bạn có thể khởi chạy một ứng dụng ở chế độ nhiều cửa sổ bằng cách nhấn vào nút Gần đây, sau đó nhấn và giữ thanh tiêu đề của ứng dụng rồi kéo ứng dụng đó vào một trong các vùng được đánh dấu trên màn hình.

  • Đổi kích thước ứng dụng của bạn ở chế độ chia đôi màn hình bằng cách kéo phần chia màn hình. Xác minh rằng ứng dụng đổi kích thước mà không gặp sự cố và có thể quan sát được các phần tử giao diện người dùng cần thiết.

  • Nếu bạn đã chỉ định các thứ nguyên tối thiểu cho ứng dụng, hãy thử đổi kích thước ứng dụng sao cho kích thước cửa sổ của ứng dụng nhỏ hơn các thứ nguyên đó. Xác minh rằng bạn không thể đổi kích thước ứng dụng thành nhỏ hơn kích thước tối thiểu đã chỉ định.

  • Thông qua tất cả các kiểm thử, hãy xác minh rằng hiệu năng của ứng dụng ở mức chấp nhận được. Chẳng hạn, xác minh rằng việc cập nhật giao diện người dùng sau khi ứng dụng thay đổi kích thước không có độ trễ quá lâu.

API cấp 31 trở lên

Nếu ứng dụng của bạn nhắm đến API cấp 31 trở lên, cũng như chiều rộng và chiều cao tối thiểu của hoạt động chính nhỏ hơn hoặc bằng các kích thước tương ứng của vùng hiển thị có sẵn, hãy xác minh tất cả hành vi được liệt kê cho API cấp 24 đến 30.

Danh sách kiểm thử

Để xác minh hiệu năng của ứng dụng ở chế độ nhiều cửa sổ, hãy thử các thao tác sau. Bạn nên thử các thao tác này ở cả chế độ chia đôi màn hình và chế độ cửa sổ trên máy tính, trừ trường hợp có lưu ý khác.

  • Chuyển vào và rời khỏi chế độ nhiều cửa sổ.

  • Chuyển từ ứng dụng của bạn sang một ứng dụng khác và xác minh rằng ứng dụng của bạn vẫn thực hiện đúng hành vi khi vẫn có thể quan sát được nhưng không ở trạng hoạt động. Ví dụ: nếu ứng dụng của bạn đang phát video, hãy xác minh rằng video tiếp tục phát trong khi người dùng đang tương tác với một ứng dụng khác.

  • Ở chế độ chia đôi màn hình, hãy thử di chuyển phần chia màn hình để làm cho ứng dụng lớn hơn và nhỏ hơn. Hãy thử các thao tác này ở cả cấu hình cạnh nhau và cấu hình trên-dưới. Xác minh rằng ứng dụng không gặp sự cố, các chức năng thiết yếu đều có thể quan sát được, cũng như thao tác đổi kích thước không mất quá nhiều thời gian.

  • Thực hiện một số thao tác đổi kích thước một cách liên tiếp. Xác minh rằng ứng dụng của bạn không gặp sự cố hoặc rò rỉ bộ nhớ. Trình phân tích bộ nhớ của Android Studio cung cấp thông tin về mức sử dụng bộ nhớ của ứng dụng (xem bài viết Kiểm tra mức sử dụng bộ nhớ của ứng dụng bằng Trình phân tích bộ nhớ).

  • Sử dụng ứng dụng của bạn bình thường trong một số cấu hình cửa sổ khác nhau và xác minh rằng ứng dụng hoạt động đúng cách. Xác minh rằng văn bản có thể đọc được và các phần tử giao diện người dùng không quá nhỏ để có thể tương tác.

Đã tắt tính năng hỗ trợ nhiều cửa sổ

Ở API cấp độ 24 đến 30, nếu bạn đã tắt tính năng hỗ trợ chế độ nhiều cửa sổ bằng cách thiết lập android:resizeableActivity="false", bạn nên khởi chạy ứng dụng của mình trên thiết bị Android phiên bản từ 7.0 đến 11, đồng thời cố gắng đưa ứng dụng đó vào chế độ chia đôi màn hình và chế độ cửa sổ trên máy tính. Xác minh rằng khi bạn làm như vậy, ứng dụng vẫn ở chế độ toàn màn hình.

Tài nguyên khác

Để biết thêm thông tin về tính năng hỗ trợ chế độ nhiều cửa sổ trong Android, hãy xem: