转载地址:http://www.jianshu.com/p/2d76430617ae
一、简介
该款APP是一个后台基于bmob后端云的社交APP,后台采用bmob云存储技术。界面采用了谷歌的matrial design设计,框架基于MD+Rxjava+retrofit+MVP架构。到目前为止,已经完成的功能模块有单聊,群聊,附近人搜索,开心时刻,天气预报,朋友圈发表和个人信息编辑展示等7大功能模块。
Github上的项目地址:https://github.com/HelloChenJinJun/TestChat
首先郑重声明下,该聊天功能的实现并不是调用官方的即时通讯API,而是本人自己结合官方提供的推送功能和实时同步的功能,按照自己的逻辑来实现的,所以内部聊天信息的逻辑处理过程源码是开放的,希望对想学习Android聊天框架的同学有所帮助。
二、ScreenShots
三、使用方法
由于个人隐私,不方便公开自己的后台,感兴趣的同学,可以自己创建一个后台。
步骤如下:
一、由于该项目后台是基于bmob,所以首先到bmob官网注册开发者账号,创建应用,把Constant类其中的KEY替换为你自己创建的application_id。
二、由于天气和定位功能是高德API提供的,所以要在高德地图开发者官网注册账号,并创建应用。把下面的value替换成自己创建的应用appkey
三、由于内部user的头像和背景默认是使用服务器上提供的图片,所以这里必须把根目录的图片内容上传到服务器上新建的sys_data表中。
相应的处理如下:
把项目的根目录avatar文件里的图片上传到文件类型的avatar字段
把项目的根目录wallpaper文件里的图片上传到文件类型的wallpaper字段。
把项目的根目录twallpaper文件里的图片上传到文件类型的twallpaper字段。
四、项目结构如下:
五、聊天原理的实现
(仅仅是流程思路,具体实现请移步源码)
5.1、单聊原理的实现:
1、首先搜索好友,根据搜索条件搜索到好友user,然后根据user中的belongId在服务器上查找用户的设备ID
2、构建邀请消息
3、将邀请消息转化为jsonObject数据,进行基于设备ID推送。
基于推送的结果进行相应的处理:
不管推送成功或失败,都要保存请求消息到服务器上面。
如果推送成功,对方在接受到消息后会在服务器上面更新该消息为已读状态,
如果推送失败,对方在开启定时检测服务时检测到该消息,并在服务器上更新为已读状态
所以不管推送成功与否,对方都能接收到消息,唯一的区别就是:推送成功的情况,消息及时性比较高,推送失败后要隔一段时间后才能收到,这里我们可以缩短定时检测的时间周期,但流量耗费有大。
这里我采取优化的策略是:
根据监听网络连接状态的变化来做相应的调整:
如果连接的是wifi:适当缩短定时检测的时间周期
如果连接的是移动网络,适当延长定时检测的时间周期
4、对方接收到邀请消息后,做如下处理:
判断本地数据库中是否已有该消息,已有,不处理,否则
在服务器上更新为已读状态,并保存到本地数据库中
通知监听界面邀请消息的到来,刷新界面
5、对方点击同意按钮,做如下处理:
在服务器上好友表中关联该用户
保存好友信息在本地数据库和内存中
更新邀请消息的状态,用于设置同意按钮不可点击
发送同意消息,流程跟上面一样
6、自己接收到同意消息后,做如下处理:
判断本地数据库中是否已有该消息,已有,不处理,否则
在服务器上关联该用户为好友,在本地数据中存储到好友表中
在服务器上更新为已读状态,并保存到本地数据库中
7、上述处理完后发送回执消息,流程和上面的发送邀请消息一样基于设备id进行推送。
8、对方接收到回执消息后,做如下处理:
在服务器上更新回执消息为已读。
在服务器和本地数据库中更新关联的聊天消息为已读。
这样经过发送邀请消息、接受邀请消息、发送同意消息、接受同意消息
、发送同意回执消息、接受同意回执消息6大步骤就正式建立了好友关系。
9、建立正常的好友关系后,就可以发送聊天消息拉拉:
发送和接受基本单聊消息流程如下:
9.1、判断网络状态。
9.2、判断是否为黑名单
9.3、判断是否是处于重发状态发送的
9.4、根据用户id,查找设备id
9.5、构建单聊消息实体,转化成jsonObject,最后基于设备id进行推送
9.6、对方接收到消息后,判断本地数据库中是否已有该消息,已有,不处理,否则
发送回执消息,在服务器上更新该聊天消息的读取状态为已读,防止被定时服务再次拉取到
保存聊天消息到数据库中,保存最近会话消息到数据库中和通知监听界面消息的到来。
5.2、群聊原理的实现:
发送和接受建群消息和流程如下:
1、根据群描述、群名、创建者id,群成员列表id,构建群结构消息实体,保存到服务器上
2、从服务器上获取该消息实体,并把该消息的id设置为群id,即groupId,并且存到本地的数据库中,
4、为每个成员在服务器上保存群结构消息。方便个人修改群名和群昵称的需要。
5、群主发送群欢迎消息给每个成员(通过直接上传构建好的群消息到指定的群消息表中,群成员会实时检测到该表的内容变化。)
6、对方接收到群结构消息后做如下操作:
6.1、在服务器上更新该消息的读取状态为已读
6.2、保存在本地数据库和内存中
6.3、通知监听界面消息的到来
6.4、在服务器上实时监听该群结构的变化。
经过上述的发送和接受监听群结构消息时,就已经正式加入群拉,就可以发送群聊消息。
7、发送和接受基本的群聊消息步骤如下:
7.1、根据内容构造群消息
7.2、保存群消息到我们实时监听的群消息表中,这里每当我们在上面保存一个群消息的时候,每个成员都能实时获取到该群消息
7.3、对方后台服务实时监听到该消息后,根据群结构消息,构建最近群会话消息,然后把最近会话和群消息保存到数据库中,最后通知监听界面刷新数据。
5.3、朋友圈实现功能如下:
1、根据内容构造说说消息
2、保存到服务器上,再从服务器上获取该说说(这样才有说说id)
3、保存到本地数据库中。
4、通过说说id通知后台服务实时监听该说说的内容变化和删除操作。
5、好友通过后台的定时拉取服务每隔一段时间拉取好友的说说消息,,或者在朋友圈界面下拉刷新,获取到好友的最近说说数据后,这里可以通过该说说的不可见人列表是否包含自己本用户,以决定是否保留该说说消息,最后在后台的实时监听服务中通过拉取得到的说说id,监听该说说的内容变化和删除操作。
6、每个好友点赞或评论等操作,都对服务器上的说说消息同步更新,以至于每个监听到该说说的好友都能实时收到该说说消息的内容变化情况。
说明下:由于评论点赞完全仿微信,所以不能显示非好友的点赞和评论!
六、数据库设计与实现
数据库我采用的是原始的Sqlite数据库,以用户id作为数据库的库名,
采取双重锁定的单例模式,对数据库访问采用可读可写访问模式。
外部存储:
数据库中包含的表有以下:
最近会话消息表(包含群聊和单聊会话)、单聊信息表、好友信息表、好友请求消息表(用户展示邀请列表)、群消息表、群结构消息表、说说消息表、微信精选信息表、趣图消息表、笑话消息表、美女图片表
内部存储:
1、主要保存在自定义的UserCacheManager、MsgCacheManager和LocationManager上面。包括全部好友信息缓存、黑名单缓存、群成员缓存、群结构缓存、本用户的信息、经纬度和地址列表。
2、基本信息存储到SharePreferences,包括以下内容:
服务器时间和本地时间的差值、每个群消息的消息提醒设置信息、是否已经登录的信息、上次用户信息更新的时间、上次更新说说的时间、上册群结构消息更新时间、上次定位的地址列表和经纬度、单聊消息的提醒设置信息、振动和声音设置信息。
七、What can be learned about this project?
1、封装toolbar,封装adapter,封装基类BaseFragment和BaseActivity的实现
2、滑动冲突的解决方案
3、底层网络访问框架的封装
4、聊天逻辑的处理思想
5、优美UI界面控件的设计
6、滑动隐现浮动按钮和菜单浮动按钮结合的实现等等。
八、使用到的开源库
主流的开源库
Rxjava 、okhttp 、gson 、retrofit 、glide 、PhotoView
其他的开源库
JDAddressSelector 一个非常不错的级联地址选择器
SwipeRecyclerView为了解决滑动冲突和基类adapter的封装,并没有直接依赖该开源库,仅仅是参考其中的侧滑思路,把他纳入到我自己的adapter基类中。
Slider 一个很不错的侧滑关闭界面的开源库
在此鸣谢以上开源项目的作者,非常感谢!
九、UI设计和参考的项目
微信、QQ。图标使用的是matirial design icon
CircleDemo一个高仿微信朋友圈的demo
ImagePicker高仿微信图片选择器
Bmob官方提供的聊天源码,非常nice,很多聊天消息处理的思维是从那里获取来的,
非常感谢!
开心时刻界面的数据来源:
干货集中营提供的api!非常nice的数据
在此感谢他们提供的数据。
十、有待完善的地方
1、后期会逐渐用RxBus替换现有的receiver,解耦和使代码更加简洁化。
2、好友分组管理
3、优化朋友圈列表,使滑动更顺畅
4、添加视频聊天
5、改善app被kill时,后台服务不能存活的现象
6、底部评论布局弹出时偏移量不合理,部分遮住内容
7、评论点赞偶尔出现丢失的情况,服务器上的问题
8、获取系统拍照后的图片文件出现file.length()为0的情况
等等(总会出现很多bug的~_~)
十一、总结
第一次写开源项目,写得不是很好,请大家多多包涵。由于最近考试比较多和忙于老师带的团队项目,时间比较紧,导致该APP最近都没时间弄,所以该APP还有很多细节未处理好,不是很完善,后期会慢慢完善该app。如果在使用的过程中出现问题,欢迎在github上留下issues或私聊我,我会尽快回复。(该app本人帐号为147,可以添加我为好友私聊我^_^)
该项目总的来说,是我大学期间自己独立开发的功能模块较多、引用第三方库比较多的社交通讯APP。在开发的过程中,我学习到了很多新的知识,比如material Design、okHttp、Retrofit、Rxjava、phototview等源码的分析和bmob平台、高德开发者平台、聚合数据平台和一些第三方库的引用,最重要的是自己独立开发该项目,让我可以自己去寻找解决方法,在寻找的过程中,收获到了很多之前所未遇到过的新知识,总结了许多bug、封装了常用的Util、适合自己的开发框架和比较好的网络访问框架。说实话,其实最大的收获并不是获取到很多新知识,而是让我拥有了独立思考问题的思维。不再是遇到问题时摆出一副束手无策的样子,只有自己探索发觉得到的经验和方法才是最适合自己的!这才是我在开发该app最大的收获!
十三、其他
本人是一名211院校大三信息管理与信息系统专业的学生,目前正在寻找andorid实习机会,如果有实习岗位,希望大家帮忙推荐下我。谢谢!
作者:傻瓜爱笨蛋
链接:http://www.jianshu.com/p/2d76430617ae
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。