Truy cập vào tập dữ liệu dùng chung

Kể từ Android 11 (API cấp 30), hệ thống sẽ lưu vào bộ nhớ đệm các tập dữ liệu lớn mà nhiều ứng dụng có thể truy cập trong các trường hợp sử dụng như học máy và phát nội dung nghe nhìn. Chức năng này giúp giảm tình trạng dư thừa dữ liệu, cả trên mạng lẫn ổ đĩa.

Khi cần quyền truy cập vào một tập dữ liệu lớn dùng chung, đầu tiên, ứng dụng của bạn có thể tìm các tập dữ liệu đã lưu vào bộ nhớ đệm này, gọi là blob dữ liệu dùng chung, trước khi xác định xem có tải một bản sao mới xuống hay không. Các ứng dụng có thể sử dụng chức năng tập dữ liệu dùng chung này thông qua các API trong BlobStoreManager.

Hệ thống sẽ duy trì các blob dữ liệu dùng chung và kiểm soát những ứng dụng nào có thể truy cập vào các blob đó. Khi ứng dụng của bạn đóng góp blob dữ liệu, bạn có thể cho biết những ứng dụng nào khác sẽ có quyền truy cập bằng cách gọi một trong các phương thức sau:

  • Để cấp quyền truy cập vào một nhóm ứng dụng cụ thể trên thiết bị, hãy chuyển tên gói của những ứng dụng này vào allowPackageAccess().
  • Để chỉ cho phép những ứng dụng có chứng chỉ được ký bằng khoá tương tự với khoá dùng cho ứng dụng của bạn, chẳng hạn như một bộ ứng dụng mà bạn quản lý, hãy gọi allowSameSignatureAccess().
  • Để cấp quyền truy cập vào tất cả các ứng dụng trên một thiết bị, hãy gọi allowPublicAccess().

Truy cập vào blob dữ liệu dùng chung

Hệ thống sẽ biểu thị từng blob dữ liệu dùng chung bằng một đối tượng BlobHandle. Mỗi thực thể của BlobHandle chứa một hàm băm được bảo mật bằng mật mã và một số thông tin nhận dạng cho tập dữ liệu.

Để truy cập vào blob dữ liệu dùng chung, hãy tải thông tin nhận dạng xuống từ máy chủ. Bằng những thông tin này, hãy kiểm tra xem tập dữ liệu đã có trên hệ thống hay chưa.

Bước tiếp theo sẽ phụ thuộc vào việc dữ liệu có sẵn hay không.

Có tập dữ liệu

Nếu tập dữ liệu đã có sẵn trên thiết bị, hãy truy cập vào tập dữ liệu đó từ hệ thống, như minh hoạ trong đoạn mã sau:

Kotlin

val blobStoreManager =
        getSystemService(Context.BLOB_STORE_SERVICE) as BlobStoreManager
// The label "Sample photos" is visible to the user.
val blobHandle = BlobHandle.createWithSha256(sha256DigestBytes,
        "Sample photos",
        System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),
        "photoTrainingDataset")
try {
    val input = ParcelFileDescriptor.AutoCloseInputStream(
            blobStoreManager.openBlob(blobHandle))
    useDataset(input)
}

Java

BlobStoreManager blobStoreManager =
        ((BlobStoreManager) getSystemService(Context.BLOB_STORE_SERVICE));
if (blobStoreManager != null) {
    // The label "Sample photos" is visible to the user.
    BlobHandle blobHandle = BlobHandle.createWithSha256(
            sha256DigestBytes,
            "Sample photos",
            System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),
            "photoTrainingDataset");
    try (InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(
            blobStoreManager.openBlob(blobHandle))) {
        useDataset(input);
    }
}

Không có tập dữ liệu

Nếu không có tập dữ liệu, hãy tải tập dữ liệu đó xuống từ máy chủ và đóng góp cho hệ thống, như minh hoạ trong đoạn mã sau:

Kotlin

val sessionId = blobStoreManager.createSession(blobHandle)
try {
    val session = blobStoreManager.openSession(sessionId)
    try {
        // For this example, write 200 MiB at the beginning of the file.
        val output = ParcelFileDescriptor.AutoCloseOutputStream(
                session.openWrite(0, 1024 * 1024 * 200))
        writeDataset(output)

        session.apply {
            allowSameSignatureAccess()
            allowPackageAccess(your-app-package,
                    app-certificate)
            allowPackageAccess(some-other-app-package,
                    app-certificate)
            commit(mainExecutor, callback)
        }
    }
}

Java

long sessionId = blobStoreManager.createSession(blobHandle);
try (BlobStoreManager.Session session =
        blobStoreManager.openSession(sessionId)) {
    // For this example, write 200 MiB at the beginning of the file.
    try (OutputStream output = new ParcelFileDescriptor.AutoCloseOutputStream(
            session.openWrite(0, 1024 * 1024 * 200)))
        writeDataset(output);
        session.allowSameSignatureAccess();
        session.allowPackageAccess(your-app-package,
                    app-certificate);
        session.allowPackageAccess(some-other-app-package,
                    app-certificate);
        session.commit(getMainExecutor(), callback);
    }
}