测试同学提了一个播放记录的bug,在测试环境,同一个专辑产生了两条播放记录。
1.通过查看本地数据库( sqlite3 ),发现确实有两条播放记录,
22439706|22439706|381931|0||2016-08-24 18:46:28|谁的青春不迷茫 不一样又怎么样。。
-22439706|22439706|381931|||2016-08-24 18:36:34|谁的青春不迷茫 不一样又怎么样。。
两条播放记录,只有专辑id不一样,一个等于视频id,一个等于负的视频id。
2.通过查看服务端数据,发现返回的播放记录里只有一条,并且如下:
videoName:谁的青春不迷茫 不一样又怎么样。。pid:22439706
iptvAlbumId:22439706
videoInfoId:22439706
跟客户端有且只有一条是对应的,并且专辑id与视频id相等。
3.播放记录的产生是根据播放列表的,查看播放列表数据,只有一条相关的:
videoId: 22439706
categoryId: 30
albumId: 0
img: http://i3.letvimg.com/lc03_yunzhuanma/201504/08/16/05/fdb6371d08dfb40d64559fb6cd86842d_29339566/thumb/2_400_300.jpg
name: 谁的青春不迷茫 不一样又怎么样。。
专辑id为0。
4.查看客户端代码,有一段逻辑是,保存数据至本地时,专辑id如果=0,取视频id的负值,并保存在本地。
接下来是上传并保存至服务端,本来客户端代码原本的意图是,如果(单片的播放记录本地专辑id为负,上传服务器时,恢复为0),但是,因为共用同一个model值,如图一,结果上传的是保存至本地时修改后的值,即视频id的负值。
而服务端会对负的专辑id做兼容,转换为正的专辑id;导致本地有两条播放记录,一条专辑id是本地保存的负的视频id,一条是服务端传过来的正的视频id。
图一:
PlayHistoryProviderUtils.java /** * insert playHistorys by roleid * * @param roleId * @param values * @return */ public static int insertPlayHistory(Long roleId, ContentValues values) { int insertCount = -1; if (values == null) { return insertCount; } PlayHistoryModel model = PlayHistoryUtils.combinePlayHistoryModel(values); try { insertCount = getHistoryDBManager(roleId) .updateToLocalDB(model); log("savePlayHistory insertCount = " + insertCount); if (insertCount > 0) { insertUptoServer(getContext(), model); } } catch (Exception ex) { log("savePlayHistory failed: " + ex); ex.printStackTrace(); } return insertCount; }
图二:
PlayHistoryUtils.java public static PlayHistoryModel combinePlayHistoryModel(ContentValues values) { PlayHistoryModel playHistoryModel = new PlayHistoryModel(); String aid = values.getAsString(HistoryFieldConstants.QUERY_FIELD_AID); // 单片的播放记录本地专辑id为负,上传服务器时,恢复为0 playHistoryModel.setIptvAlbumId((StringUtils.equalsNull(aid) || Integer .parseInt(aid) < 0) ? 0 : Long.valueOf(aid));
图三:
PlayHistoryDBManager.java private int saveHistoryToLocal(PlayHistoryModel model) throws SQLException { if (model == null) { return -1; } if (model.getIptvAlbumId() == null || model.getIptvAlbumId() == 0) {// 单片以-videoid // 作为专辑id(主键)存数据库 if (model.getVideoInfoId() == null) { return -1; } model.setIptvAlbumId(-model.getVideoInfoId()); }
5.修改方案:本地和上传服务端使用的model对象独立。如下图
图四
PlayHistoryProviderUtils.java /** * insert playHistorys by roleid * * @param roleId * @param values * @return */ public static int insertPlayHistory(Long roleId, ContentValues values) { int insertCount = -1; if (values == null) { return insertCount; } try { PlayHistoryModel localModel = PlayHistoryUtils.combinePlayHistoryModel(values); insertCount = getHistoryDBManager(roleId) .updateToLocalDB(localModel); log("savePlayHistory insertCount = " + insertCount + ", historyModel = " + localModel); if (insertCount > 0) { PlayHistoryModel serverModel = PlayHistoryUtils.combinePlayHistoryModel(values); insertUptoServer(getContext(), serverModel); } } catch (Exception ex) { log("savePlayHistory failed: " + ex); ex.printStackTrace(); } return insertCount; }