博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Wear开发 - 数据通讯 - 第四节 : 数据封装(解决不能序列化问题)
阅读量:6608 次
发布时间:2019-06-24

本文共 3222 字,大约阅读时间需要 10 分钟。

一. 前言

背景

一开始笔者在研究数据发送与接收的时候,看到Wear数据类DataMap除了可以put基本类型外,还有个fromBundle方法来构建一个DataMap对象。所以一口气的将原本功能上的序列化对象传递过去,结果手表端一直都收不到消息。

问题原因

后来查阅了开发者文档,发现这个Bundle并没有我们在Intent中传递数据的那么强大,它并不支持序列化!先附上开发者文档的说明:

Returns a DataMap from a Bundle. The input Bundle is expected to contain only elements supported by DataMap. Any elements in the Bundle not supported by DataMap will be dropped.

关键的一句是"The input Bundle is expected to contain only elements supported by DataMap",只有DataMap本身支持的类型才能被传递到Bundle中,那么也就是说我们自己构建的数据Bean并不能够直接序列化传进Bundle中,这导致结果是"Any elements in the Bundle not supported by DataMap will be dropped",即这些数据不会被传递,而是会被抛弃。

问题来了

那么,问题来了!怎么样才能够优雅地传递数据Bean呢?

接下来笔者将给出自己的解决方案。

二. 解决方案

1. 使用公共工程

  1. 创建公共工程:因为数据在Phone工程Wear工程是共用,为了避免在这两个工程中都各自持有数据类,最好的方式自然是将这部分抽出来。创建完毕后,打钩"Is Library",将公共工程设置为库工程。
  2. 导入公共工程:Phone工程Wear工程都引用公共工程。
  3. 公共工程模板:以下用一个城市数据作为样例。注意:要使用DataMap这个类,必须引用5.0版本以上的GooglePlayServices。

import com.google.android.gms.wearable.DataMap;public class WearCityBean {public static final String KEY = "/bean/wear/city";private static final String M_CITY_ID = "mCityId";private static final String M_CITY_NAME = "mCityName";private static final String M_COUNTRY_NAME = "mCountryName";// 城市IDprivate String mCityId;// 城市名private String mCityName;// 国家名private String mCountryName;public WearCityBean() {}public WearCityBean(DataMap map) {    setCityId(map.getString(M_CITY_ID));    setCityName(map.getString(M_CITY_NAME));    setCountryName(map.getString(M_COUNTRY_NAME));}public DataMap getDataMap() {    DataMap map = new DataMap();    map.putString(M_CITY_ID, mCityId);    map.putString(M_CITY_NAME, mCityName);    map.putString(M_COUNTRY_NAME, mCountryName);    return map;}public String getCityId() {    return mCityId;}public void setCityId(String cityId) {    mCityId = cityId;}public String getCityName() {    return mCityName;}public void setCityName(String cityName) {    mCityName = cityName;}public String getCountryName() {    return mCountryName;}public void setCountryName(String countryName) {    mCountryName = countryName;}@Overridepublic String toString() {    return "WearCityBean [mCityId=" + mCityId + ", mCityName=" + mCityName            + ", mCountryName=" + mCountryName + "]";}}

关键代码分析 - 发送数据:要发送数据的一端,将一个DataMap对象传入到这个方法中,将Bean自身的基本数据传递到DataMap中。这样,要发送数据的那一端就不用存在很多零散的代码,而且如果Phone端和Wear端都要实现数据发送的话,就不用重复两份代码了。

public DataMap getDataMap() {    DataMap map = new DataMap();    map.putString(M_CITY_ID, mCityId);    map.putString(M_CITY_NAME, mCityName);    map.putString(M_COUNTRY_NAME, mCountryName);    return map;}

发送端代码:下面通过先初始化一个WearCityBean对象后,再从中获取DataMap对象,最后再放到数据请求对象PutDataMapRequest中,完成发送的封装。

private void packageCityData(PutDataMapRequest dataMap) {//通过getWearCityBean()构建并初始化数据对象WearCityBean wearCityBean = getWearCityBean();DataMap map = wearCityBean.getDataMap();dataMap.getDataMap().putDataMap(WearCityBean.KEY, map);}

关键代码分析 - 接收数据:将收到的DataMap用来构建一个WearCityBean对象,即可完成数据的解析。

public WearCityBean(DataMap map) {    setCityId(map.getString(M_CITY_ID));    setCityName(map.getString(M_CITY_NAME));    setCountryName(map.getString(M_COUNTRY_NAME));}
  1. 接收端的代码过于简单,就不再附上了。

后话

  • 以上是笔者在API不够满足需求的情况下想出的一套解决方案,经过多次测试,运行良好。
  • 除了直接的将基本数据类型传入DataMap中之外,还可以用Json或者其他方式将数据封装成一个String,再传入到DataMap中。这也是一个不错的方案。

转载地址:http://thiso.baihongyu.com/

你可能感兴趣的文章
2-11
查看>>
Appium IOS
查看>>
POJ1961 Period [KMP应用]
查看>>
CSS hack
查看>>
IT项目管理工具探讨之_项目群管理
查看>>
如何在 Android 手机上安装 Ubuntu 13.04
查看>>
HDU 6073 - Matching In Multiplication | 2017 Multi-University Training Contest 4
查看>>
topcoder srm 465 div1
查看>>
C语言 scanf()和gets()函数的区别
查看>>
如何检测域名是否被微信屏蔽 微信域名检测接口API是如何实现
查看>>
POJ1611-The Suspects
查看>>
Spring 中 ApplicationContext 和 BeanFactory 的区别
查看>>
Linux Makefile 生成 *.d 依赖文件及 gcc -M -MF -MP 等相关选项说明【转】
查看>>
Linux下安装Python-3.3.2【转】
查看>>
STL杂记
查看>>
LeetCode OJ:Merge Two Sorted Lists(合并两个链表)
查看>>
功能测试
查看>>
Rust的闭包
查看>>
【BZOJ 1901】Dynamic Rankings
查看>>
阿里架构师都在学的知识体系
查看>>