Đồng bộ hoá các mục dữ liệu với Data Layer API

DataItem xác định giao diện mà hệ thống sử dụng để đồng bộ hoá dữ liệu giữa thiết bị cầm tay và thiết bị đeo. DataItem thường bao gồm các thành phần sau:

  • Tải trọng: Một mảng byte mà bạn có thể thiết lập bằng dữ liệu, cho phép bạn thực hiện quá trình chuyển đổi tuần tự hoặc quá trình huỷ chuyển đổi tuần tự đối tượng riêng. Kích thước tải trọng được giới hạn ở 100 KB.
  • Đường dẫn: Một chuỗi duy nhất phải bắt đầu bằng dấu gạch chéo xuôi, chẳng hạn như "/path/to/data".

Lưu ý: API Lớp dữ liệu chỉ có thể gửi thông báo và đồng bộ hoá dữ liệu với điện thoại Android hoặc đồng hồ Wear OS. Nếu thiết bị Wear OS của bạn được ghép nối với thiết bị iOS, thì API Lớp dữ liệu sẽ không hoạt động.

Vì lý do này, đừng nên sử dụng API Lớp dữ liệu làm phương thức chính để giao tiếp với mạng. Thay vào đó, hãy dùng cùng một mẫu như ứng dụng di động với một số điểm khác biệt nhỏ.

Bạn thường không triển khai DataItem trực tiếp. Thay vào đó, bạn sẽ làm như sau:

  1. Tạo đối tượng PutDataRequest, chỉ định một đường dẫn chuỗi để nhận dạng duy nhất mục đó.
  2. Gọi setData() để đặt trọng tải.
  3. Nếu sự chậm trễ trong quá trình đồng bộ hoá gây ảnh hưởng không tốt đến trải nghiệm người dùng, hãy gọi setUrgent().
  4. Sử dụng phương thức putDataItem của lớp DataClient để yêu cầu hệ thống tạo mục dữ liệu.

Khi yêu cầu các mục dữ liệu, hệ thống sẽ trả về các đối tượng giúp triển khai giao diện DataItem đúng cách. Tuy nhiên, thay vì thao tác với các byte thô bằng setData(), bạn nên sử dụng bản đồ dữ liệu để biết một mục dữ liệu có giao diện giống với Bundle.

Để biết thêm thông tin, hãy xem ứng dụng Mẫu DataLayer.

Đồng bộ hoá dữ liệu với bản đồ dữ liệu

Hãy sử dụng lớp DataMap khi có thể. Phương pháp này cho phép bạn xử lý các mục dữ liệu dưới dạng Android Bundle, nhờ đó hệ thống sẽ thực hiện quá trình chuyển đổi tuần tự hoặc quá trình huỷ chuyển đổi tuần tự đối tượng cho bạn, đồng thời bạn có thể thao tác dữ liệu với các cặp khoá-giá trị.

Để sử dụng bản đồ dữ liệu:

  1. Tạo một đối tượng PutDataMapRequest, đặt đường dẫn của mục dữ liệu.

    Lưu ý: Chuỗi đường dẫn là giá trị nhận dạng duy nhất cho mục dữ liệu, cho phép bạn truy cập mục đó từ một trong hai bên của kết nối. Đường dẫn phải bắt đầu bằng một dấu gạch chéo xuôi. Nếu bạn đang sử dụng dữ liệu phân cấp trong ứng dụng, hãy tạo một lược đồ đường dẫn khớp với cấu trúc của dữ liệu.

  2. Gọi PutDataMapRequest.getDataMap() để lấy bản đồ dữ liệu mà bạn có thể đặt các giá trị.
  3. Đặt giá trị cho bản đồ dữ liệu bằng các phương thức put...(), chẳng hạn như putString().
  4. Nếu độ trễ trong quá trình đồng bộ hoá ảnh hưởng tiêu cực đến trải nghiệm người dùng, hãy gọi setUrgent().
  5. Gọi PutDataMapRequest.asPutDataRequest() để lấy đối tượng PutDataRequest.
  6. Sử dụng phương thức putDataItem của lớp DataClient để yêu cầu hệ thống tạo mục dữ liệu.

    Lưu ý: Nếu thiết bị cầm tay và thiết bị đeo bị ngắt kết nối, dữ liệu sẽ được lưu vào bộ đệm và đồng bộ hoá khi kết nối được thiết lập lại.

Phương thức increaseCounter() trong ví dụ sau cho biết cách tạo bản đồ dữ liệu và đặt dữ liệu vào bản đồ đó.

Kotlin

private const val COUNT_KEY = "com.example.key.count"

class MainActivity : Activity() {

    private lateinit var dataClient: DataClient
    private var count = 0
    ...
    // Create a data map and put data in it
    private fun increaseCounter() {
        val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run {
            dataMap.putInt(COUNT_KEY, count++)
            asPutDataRequest()
        }
        val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq)
    }
    ...
}

Java

public class MainActivity extends Activity {
    private static final String COUNT_KEY = "com.example.key.count";
    private DataClient dataClient;
    private int count = 0;
    ...
    // Create a data map and put data in it
    private void increaseCounter() {
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
        Task<DataItem> putDataTask = dataClient.putDataItem(putDataReq);
    }
  ...
}

Để biết thêm thông tin về cách xử lý Tasks, hãy xem tài liệu tham khảo.

Đặt mức độ ưu tiên của DataItem

API DataClient cho phép sử dụng các yêu cầu khẩn cấp để đồng bộ hoá đối tượng DataItem. Thông thường, hệ thống trì hoãn việc phân phối các mục dữ liệu đến mạng Wear OS để cải thiện thời lượng pin cho thiết bị của người dùng. Tuy nhiên, nếu độ trễ trong việc đồng bộ hoá các mục dữ liệu ảnh hưởng tiêu cực đến trải nghiệm người dùng, bạn có thể đánh dấu các mục đó là khẩn cấp. Ví dụ: trong một ứng dụng điều khiển từ xa mà người dùng muốn các thao tác của mình được phản ánh ngay lập tức, bạn có thể gọi setUrgent() để hệ thống đồng bộ hoá ngay các mục dữ liệu.

Nếu bạn không gọi setUrgent(), hệ thống có thể trì hoãn tối đa 30 phút trước khi đồng bộ hoá các mục dữ liệu không khẩn cấp, mặc dù thời gian trễ thường chỉ là vài phút. Mức độ khẩn cấp mặc định là không khẩn cấp, vì vậy, bạn phải sử dụng setUrgent() nếu cần giữ lại hành vi đồng bộ hoá tức thì từ các phiên bản trước của API Wear OS.

Theo dõi sự kiện mục dữ liệu

Nếu một bên của kết nối lớp dữ liệu thay đổi một mục dữ liệu, hãy thông báo cho người dùng về mọi thay đổi ở phía bên kia của kết nối. Bạn có thể thực hiện việc này bằng cách triển khai trình nghe sự kiện mục dữ liệu.

Đoạn mã trong ví dụ sau sẽ thông báo cho ứng dụng khi giá trị của bộ đếm được xác định trong ví dụ trước thay đổi:

Kotlin

private const val COUNT_KEY = "com.example.key.count"

class MainActivity : Activity(), DataClient.OnDataChangedListener {

    private var count = 0

    override fun onResume() {
        super.onResume()
        Wearable.getDataClient(this).addListener(this)
    }

    override fun onPause() {
        super.onPause()
        Wearable.getDataClient(this).removeListener(this)
    }

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        dataEvents.forEach { event ->
            // DataItem changed
            if (event.type == DataEvent.TYPE_CHANGED) {
                event.dataItem.also { item ->
                    if (item.uri.path.compareTo("/count") == 0) {
                        DataMapItem.fromDataItem(item).dataMap.apply {
                            updateCount(getInt(COUNT_KEY))
                        }
                    }
                }
            } else if (event.type == DataEvent.TYPE_DELETED) {
                // DataItem deleted
            }
        }
    }

    // Method to update the count
    private fun updateCount(int: Int) { ... }
    ...
}

Java

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {
    private static final String COUNT_KEY = "com.example.key.count";
    private int count = 0;

    @Override
    protected void onResume() {
        super.onResume();
        Wearable.getDataClient(this).addListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        Wearable.getDataClient(this).removeListener(this);
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_CHANGED) {
                // DataItem changed
                DataItem item = event.getDataItem();
                if (item.getUri().getPath().compareTo("/count") == 0) {
                    DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                    updateCount(dataMap.getInt(COUNT_KEY));
                }
            } else if (event.getType() == DataEvent.TYPE_DELETED) {
                // DataItem deleted
            }
        }
    }

    // Method to update the count
    private void updateCount(int c) { ... }
    ...
}

Hoạt động này sẽ triển khai giao diện DataClient.OnDataChangedListener. Hoạt động này tự thêm nó làm trình nghe sự kiện mục dữ liệu bên trong phương thức onResume() và xoá trình nghe trong phương thức onPause(). Để xem cách triển khai bằng hình ảnh, mô hình khung hiển thị và dịch vụ, hãy xem ứng dụng Mẫu DataLayer.

Bạn cũng có thể triển khai trình nghe ở dạng dịch vụ. Để biết thêm thông tin, hãy xem phần Theo dõi sự kiện Lớp dữ liệu.