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

Trong Android 9 (trở xuống), các ứng dụng được chuyển sang trạng thái PAUSED khi:

  • Một hoạt động mới, mờ được chạy trên ứng dụng, trong khi ứng dụng vẫn hiển thị (và do đó, không bị dừng).
  • Hoạt động đã mất tiêu điểm nhưng không bị che khuất và người dùng có thể tương tác với hoạt động đó. Ví dụ: ở chế độ nhiều cửa sổ, một số hoạt động có thể hiển thị và nhận dữ liệu đầu vào cảm ứng đồng thời.

Các tình huống này khác nhau về mức độ tạm dừng mà ứng dụng phải thực hiện nhưng không thể phân biệt được ở cấp ứng dụng.

Trong Android 10, tất cả hoạt động có thể lấy tiêu điểm ở trên cùng trong ngăn xếp hiển thị đều ở trạng thái RESUMED. Điều này giúp cải thiện khả năng tương thích với chế độ Nhiều cửa sổ và MD cho các ứng dụng sử dụng onPause() thay vì onStop() để ngừng làm mới giao diện người dùng và tương tác với người dùng. Điều này có nghĩa là:

  • Cả hai hoạt động ở chế độ chia đôi màn hình đều được tiếp tục.
  • Tất cả hoạt động hiển thị trên cùng ở chế độ cửa sổ hình dạng tuỳ ý sẽ được tiếp tục.
  • Bạn có thể tiếp tục các hoạt động trên nhiều màn hình cùng một lúc.

Hình 1. Tiếp tục nhiều lần trên thiết bị có thể gập lại

Hình 2. Tiếp tục nhiều lần ở chế độ máy tính

Các hoạt động có thể ở trạng thái PAUSED khi không thể lấy làm tâm điểm hoặc bị che khuất một phần, chẳng hạn như:

  • Ở chế độ chia đôi màn hình thu nhỏ (với trình chạy ở bên cạnh), hoạt động trên cùng sẽ không được tiếp tục vì không thể lấy tiêu điểm.
  • Ở chế độ hình trong hình, hoạt động sẽ không tiếp tục vì không thể lấy tiêu điểm.
  • Khi hoạt động thuộc các hoạt động minh bạch khác trong cùng một ngăn xếp.

Phương pháp này cho các ứng dụng biết rằng một hoạt động chỉ có thể nhận dữ liệu đầu vào từ người dùng ở trạng thái RESUMED. Trước Android 10, các hoạt động cũng có thể nhận dữ liệu đầu vào ở trạng thái PAUSED (ví dụ: hãy thử chạm vào cả hai hoạt động ở chế độ chia đôi màn hình trên một thiết bị chạy Android 9).

Để duy trì tín hiệu tiếp tục từ các bản phát hành Android trước (và để thông báo thời điểm ứng dụng nên có quyền truy cập vào tài nguyên quyền truy cập độc quyền hoặc singleton), Android 10 bao gồm một lệnh gọi lại mới:

Activity#onTopResumedActivityChanged(boolean onTop)

Khi được gọi, lệnh gọi lại này sẽ được gọi giữa Activity#onResume()Activity#onPause(). Lệnh gọi lại này là không bắt buộc và có thể bị bỏ qua, vì vậy, một hoạt động có thể chuyển từ trạng thái RESUMED sang trạng thái PAUSED mà không trở thành hoạt động ở trên cùng trong hệ thống. Ví dụ: ở chế độ nhiều cửa sổ. Vì lệnh gọi lại này là không bắt buộc, nên nó không thuộc Vòng đời hoạt động và hiếm khi được sử dụng.

Hoạt động được tiếp tục hàng đầu trước đó nhận được và hoàn tất việc thực thi onTopResumedActivity(false) trước khi hoạt động được tiếp tục hàng đầu tiếp theo nhận được onTopResumedActivity(true) trừ khi hoạt động trước đó mất quá nhiều thời gian để xử lý lệnh gọi phương thức và đạt đến thời gian chờ 500 mili giây.

Khả năng tương thích

Để duy trì khả năng tương thích khi triển khai tính năng tiếp tục nhiều lần, hãy cân nhắc các giải pháp sau đây.

Nhiều hoạt động được tiếp tục trong một quy trình của ứng dụng

  • Vấn đề. Trong Android 9 trở xuống, mỗi lần chỉ có một hoạt động trong hệ thống được tiếp tục. Mọi quá trình chuyển đổi giữa các hoạt động đều liên quan đến việc tạm dừng một hoạt động trước khi tiếp tục một hoạt động khác. Một số ứng dụng và khung (chẳng hạn như Flutter hoặc LocalActivityManager của Android) sử dụng thực tế này và lưu trữ trạng thái về hoạt động tiếp tục trong singleton.
  • Giải pháp. Trên Android 9 trở xuống, nếu 2 hoạt động từ cùng một quy trình được tiếp tục, hệ thống chỉ tiếp tục hoạt động cao hơn theo thứ tự Z. Các ứng dụng nhắm đến Android 10 có thể hỗ trợ nhiều hoạt động được tiếp tục cùng một lúc.

Quyền truy cập đồng thời vào camera

  • Vấn đề. Những vấn đề này cũng xảy ra trên Android 9 trở xuống. Ví dụ: một hoạt động ở chế độ toàn màn hình và tiếp tục có thể mất tiêu điểm máy ảnh vào một hoạt động đã tạm dừng ở trên cùng ở chế độ hình trong hình, nhưng sẽ hiển thị nhiều hơn khi áp dụng rộng rãi hơn các chế độ nhiều cửa sổ và nhiều màn hình.
    • Do các thay đổi đối với trạng thái RESUME, các ứng dụng có thể bị ngắt kết nối với máy ảnh ngay cả khi tiếp tục. Để giải quyết vấn đề này, ứng dụng phải xử lý việc ngắt kết nối máy ảnh mà không gặp sự cố. Khi bị ngắt kết nối, ứng dụng sẽ nhận được lệnh gọi lại bị ngắt kết nối và tất cả lệnh gọi vào API sẽ bắt đầu gửi CameraAccessException.
    • 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.
  • Giải pháp. Nhà phát triển nên đưa vào logic cho trường hợp ứng dụng bị ngắt kết nối với máy ảnh. Nếu bị ngắt kết nối với máy ảnh, ứng dụng sẽ theo dõi các lệnh gọi lại về tình trạng hoạt động của máy ảnh để cố gắng kết nối lại và tiếp tục sử dụng máy ảnh. Ngoài lệnh gọi lại CameraManager#AvailabilityCallback#onCameraAvailable() hiện có, Android 10 đã thêm CameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged(), bao gồm trường hợp tiêu điểm (và mức độ ưu tiên của máy ảnh) chuyển đổi giữa một số hoạt động tiếp tục. Nhà phát triển ứng dụng nên sử dụng cả hai lệnh gọi lại này để xác định thời điểm thích hợp để thử truy cập vào máy ảnh.

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

Trong Android 10, trạng thái vòng đời hoạt động được xác định theo chế độ hiển thị và thứ tự Z. Để đảm bảo trạng thái chính xác sau khi cập nhật chế độ hiển thị trên một hoạt động và đánh giá trạng thái vòng đời nào có thể áp dụng, hãy gọi phương thức ActivityRecord#makeActiveIfNeeded() từ nhiều vị trí. Trong Android 10, trạng thái đang hoạt động có nghĩa là RESUMED hoặc PAUSED và chỉ hoạt động trong hai phiên bản này.

Trong Android 10, việc tiếp tục một hoạt động sẽ được theo dõi riêng trong từng ngăn xếp thay vì ở một vị trí duy nhất trong hệ thống. Điều này là do có thể thực hiện đồng thời một số chuyển đổi hoạt động ở chế độ nhiều cửa sổ. Để biết thông tin chi tiết, hãy xem ActivityStack#mInResumeTopActivity.

Lệnh gọi lại hoạt động tiếp tục hàng đầu

Sau các hành động có thể dẫn đến thay đổi hoạt động hàng đầu (chẳng hạn như khởi chạy, tiếp tục hoặc thay đổi thứ tự Z của hoạt động), ActivityStackSupervisor#updateTopResumedActivityIfNeeded() sẽ được gọi. Phương thức này kiểm tra xem hoạt động tiếp tục ở trên cùng có thay đổi hay không và thực hiện cập nhật nếu cần. Nếu hoạt động tiếp tục hàng đầu trước đó chưa phát hành trạng thái tiếp tục hàng đầu, thì thông báo mất trạng thái tiếp tục hàng đầu sẽ được gửi đến hoạt động đó và thời gian chờ sẽ được lên lịch ở phía máy chủ (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()). Báo cáo về trạng thái tiếp tục hàng đầu sẽ được gửi đến hoạt động tiếp theo sau khi hoạt động trước đó phát hành trạng thái hoặc khi hết thời gian chờ (xem cách sử dụng:

ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()

Một mục giao dịch TopResumedActivityChangeItem mới đã được thêm vào để báo cáo các thay đổi về trạng thái được tiếp tục hàng đầu cho ứng dụng và tận dụng cấu trúc ActivityLifecycler từ Android 9.

Trạng thái đã tiếp tục hàng đầu được lưu trữ ở phía máy khách và mỗi khi hoạt động chuyển đổi sang RESUMED hoặc PAUSED, hệ thống cũng kiểm tra xem có nên gọi lệnh gọi lại onTopResumedActivityChanged() hay không. Điều này cho phép phân tách một số hoạt động trong quá trình giao tiếp các trạng thái vòng đời và trạng thái đã tiếp tục hàng đầu giữa phía máy chủ và phía máy khách.