获取 JSON 数据到可穿戴设备的有效方法

Efficient Way To Get JSON Data To Wearable

我正在尝试以 JSON 对象的形式从 URL 读取提要,并将该提要传递给可穿戴设备以使用数据 [=18] 显示为列表=].这个 JSON 对象包含一个对象数组,每个对象包含一些元素。像这样:

{ "items":[
    { "title":"item 1", "element_1":"element 1", "element_2":"element 2" }
    { "title":"item 2", "element_1":"element 1", "element_2":"element 2" }
    { "title":"item 3", "element_1":"element 1", "element_2":"element 2" }
]}

我可以使用 GSON 或 Jackson(尽管我认为我更喜欢 GSON)将这些项目放入 ArrayList 个对象中,但我不知道如何才能做到这一点 ArrayList可穿戴设备的对象。据我所知,我不能。我想知道是否有办法做到这一点,或者如果没有,关于我应该如何去做的某种最佳实践?我是否应该将 JSON 作为字符串获取,将字符串传递给可穿戴设备,然后再对其进行解析?我不知道如果字符串非常大,这是否会效率低下,考虑到我不知道 JSON 对象的列表会有多大。我也知道可以用 GSON 解析字符串,但我不知道这是否也很低效。

一般建议是向可穿戴设备发送它需要的最少数据,并在手持设备上进行最大处理 ,因为它有更多的处理能力(和电池)。
根据文档: https://developers.google.com/android/reference/com/google/android/gms/wearable/DataItem.html#setData(byte[])
当前的最大数据项大小限制约为 100k。数据项一般应远小于此限制。
如果这适合您的需要,您应该做出决定 - 如果可以接收非常大的JSON,也许您可​​以在手持设备端拆分它,或者您可以过滤其中的一些数据。

如果您认为这对您的情况不可行,那么也许您应该修改您的要求!


我正在处理 JSON 直接在可穿戴设备上使用 GSON,对于我的用例来说它工作得很好。

我找到了 Android 磨损示例 XYZTouristAttractions,这是我当前基于该示例的代码。首先,我创建了一个共享库来减少重复代码。此共享库包含保存 JSON 数据的 Item class。我在手持设备上的 DownloadArrayListTask 中使用这个 class,它从输入流中获取 JSON 对象并将数据放入 ArrayListItem 对象中.

@Override
protected ArrayList<Item> doInBackground(URL... params) {
    URL url = params[0];
    ArrayList<Item> items = new ArrayList<>();

    try {
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        try {
            InputStreamReader input = new InputStreamReader(connection.getInputStream());

            Type listType = new TypeToken<Map<String, ArrayList<Item>>>(){}.getType();
            Gson gson = new GsonBuilder().create();
            Map<String, ArrayList<Item>> treeMap = gson.fromJson(input, listType);
            items = treeeMap.get("items");

            input.close();
        } finally {
            connection.disconnect();
        }
    } catch (IOException exception) {
        exception.printStackTrace();
    }

    return items
}

ArrayListDataLayerListenerService 中分解为字符串,并放置在 ArrayListDataMap 对象中供可穿戴设备接收。

@Override
public void onMessageReceived(MessageEvent messageEvent) {
    GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API).build();

    ConnectionResult connectionResult = googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
    if(!connectionResult.isSuccess()) {
        Log.e(TAG, "Failed to connect to Google API Client");
        return;
    }

    if(messageEvent.getPath().equals("/update_path") {
        ArrayList<Item> items = new ArrayList<>()
        try {
            items = new DownloadArrayListTask().execute(new URL("http://my_url")).get();
        } catch (MalformedURLException | InterruptedException | ExecutionException exception) {
            exception.printStackTrace();
        }

        ArrayList<DataMap> itemMaps = new ArrayList<>(items.size());

        for(Item item : items) {
            DataMap dataMap = new DataMap();
            dataMap.putString("title", item.getTitle());
            dataMap.putString("element1", item.getElement1());
            dataMap.putString("element2", item.getElement2());

            itemMaps.add(dataMap);
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await();

                for(Node node : nodes.getNodes()) {
                    PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/item_path");
                    dataMapRequest.getDataMap().putDataMapArrayList("item_key", itemMaps);

                    PutDataRequest request = dataMapRequest.asPutDataRequest();
                    DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await();

                    if(!result.getStatus().isSuccess()) {
                        Log.d(TAG, "Failed to send data");
                    }
                } 
            }
        }).start();
    }
}

然后可穿戴设备接收到这个 ArrayList of DataMap 对象,并使用它自己的 AsyncTask 将它们放回 ArrayList of Item对象。

@Override
protected ArrayList<Item> doInBackground(Uri... params) {
    Uri uri = params[0];
    ArrayList<Item> items = new ArrayList<>();

    GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API).build();

    ConnectionResult connectionResult = googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
    if(!connectionResult.isSuccess()) {
        Log.e(TAG, "Failed to connect to Google API Client");
        return;
    }

    DataItemBuffer results = Wearable.DataApi.getDataItems(googleApiClient).await();

    if(results.getStatus().isSuccess() && results.getCount() != 0) {
        DataMapItem dataMapItem = DataMapItem.fromDataItem(results.get(0);

        List<DataMap> data = dataMapItem.getDataMap().getDataMapArrayList("item_key");

        for(DataMap dataItem : data) {
            Item item = new Item(dataItem.getString("title"),
                    dataItem.getString("element1"),
                    dataItem.getString("element2"));
            items.add(item);
        }
    } else {
        Log.d(TAG, "Failed to obtain data");
    } return items;
}