独立开发 一个社交 APP 的架构分享 (已实现)

(本博客为原创:https://cloud.tencent.com/developer/user/1148436/activities)

My BananaCloud Android Application

前言: 这算是我的第一个 完完全全 由自己开发的社交类安卓APP,截止2016-7-15,第二版本的优化完善已顺利完成,可以正常使用。下面我将一 一讲述各个点,日后如果不上线,那么将考虑全面开源,含移动端代码、服务器接口代码,留意我的 GitHub。   由于内容十分地多,我尽我自己的能力将各个功能模块的做法尽可能地去讲清楚,欢迎留言,有问必复,文章会不断更新,下面所有谈及的功能皆已实现。

目录:(点击可跳转)

一 、功能架构

二 、移动端架构概述

三、服务端架构概述

一、功能架构

公共部分
  • 所有用户头像显示圆形,点击即跳转到详情页面
  • 详情页面可以看到该用户的所有帖子操作记录,头像和背景图片
  • 帖子、文章图片点击是看大图的效果,支持双指缩放,多图侧滑切换,无限循环
用户管理
  • 注册
    • 只能手机号,有短信验证
    • 可选择同时上传头像
    • 忘记密码
  • 登录
    • 公共部分
      • 登录设置缓存,一次登录后,不退出的话,那么以后的不用重复输入
    • 登录方式
      • 手机号码登录
      • 第三方登录,含微信、新浪微博
帖子模块
  • 发布
    • 文字输入,包含敏感词检索,例如脏话
    • 图片选择,含相册或拍照,可以移出
    • 视频录制,自定义时间长度、断点录制,支持预览
    • 共享位置
  • 浏览:
    • 公共部分
      • 都会显示出用户头像、发帖或评论的时间和评论的数目
    • 按编辑
      • 图文混排类型
      • 图文加视频录制类型
    • 按类型(内容布局各不相同)
      • 圈子,可以发布视频,显示位置
      • 我的作品,图文混排,瀑布流显示
      • 创业,不开启评论与点赞
  • 操作:
    • 帖子评论与评论的回复,包含表情的插入
    • 帖子与评论的点赞与撤销点赞
    • 分享、收藏、举报、信息分享到微信等平台、删除(帖主)等功能
文章模块
  • 浏览:
    • 内容页纯html,网页浏览
  • 发布:
    • 由管理员通过网页后台编辑发布,形成html标签流
  • 兼容:
    • 使用x5浏览器内核显示,效果和微信相似,包括视频播放
  • 权限
    • 除了不能被帖子点赞,其他同帖子操作
我的模块(用户信息)
  • 我的背景图片
    • 显示在个人信息页面
    • 点击可以修改,含剪辑
  • 我的消息模块
    • 推送
    • 点赞提醒
    • 评论与回复提醒
    • 显示效果为小红点和消息数目的提示
  • 资料管理模块
    • 头像图片修改,含剪辑
    • 昵称修改
    • 密码修改
    • 性别修改
    • 签名、手机、邮箱、微信、兴趣爱好等个人资料的显示修改
  • 帖子管理
    • 公共部分,点击某一条,都会跳转进入对应帖子或文章
    • 我的帖子模块,显示所有发过的帖子
    • 我的评论,显示所有发过的评论,包含回复
    • 我喜欢的模块,显示所有点过赞的帖子或评论
    • 我的收藏模块,显示所有收藏过的帖子或文章
  • 我的设置模块
    • 操作记录私有,开启了,别的用户无法查看你的操作记录
    • 推送设置的开启与否
    • 缓存清理
    • 检测更新
    • 意见反馈
    • 分享给朋友
    • 关于我们以及评分
搜索模块
  • 功能
    • 支持模糊搜索
    • 具备搜索的历史缓存
  • 类型
    • 搜索各类帖子
    • 搜索历史记录
    • 搜索用户
    • 搜索文章

说实话,这个项目的文件夹已达1.5G,安装包混淆编译后27M,我在写之前,就在想要怎么把它摊开来讲,想想真的很复杂,脑子东西东西太多。

二、移动端架构概述

1,框架层
  • 图片部分       在说使用的框架之前,先说说,APP安装包的大小的影响,包的大小可以算进去用户体验的一部分,过多地使用框架只会加大APK体积和内存消耗,例如 static final int/String 或 65535限制,在使用框架的时很多时候,都是只使用其中的一个功能。       现在我只保留了一个,不包括第三方SDK,例如OneKeyShare,保留的是 imageLoader,保留它的原因是,它的功能就是显示图片,而对于图片这类数据,可以说是占内存最大的大头,我能力有限,暂时还不能利用系统库封装好个比imageLoader更好的库,同类的库还有 picasso、fresco、volley等,曾经也引入过 fresco,比imageLoader多了很多API,考虑到框架的成熟性最后没使用,volley就不仅仅是显示个图片那么简单了,还有网络请求,上传等,网络请求和上传的代码这部分因为我自己能够写出还不错的几个函数,所以为了减少不必要的消耗,没使用volley。
  • 网络部分        上面说到volley具备网络的大部分需求,例如get、post请求操作,除了这个,还有 android-async-http、okHttp 等,这些我都有了解过,也在别的项目里面使用过,但我没使用到BananaCloud,原因就是上面谈到的网络请求和上传的代码这部分,如果自己封装好,且封装得不错,就不需要再去使用框架。
  • 富文本编辑器        这个在一个月前还有使用,基于gitHub 安卓开源项目-richEditor二次开发而来,原作者的项目,bug比较多,且兼容性非常差,在我修改完之后,最后一次发现bug是在红米手机上面,编辑框完全失效,逐弃之。修改的教程请转移到我的博文:点我
  • 视频播放器
    • 原生
      • Ijkplayer(轻量级) 它是Blibli技术团队开源的一个视频播放框架,原框架需要自己编译.so,我当时在他们的基础上编译和封装好了一个,详情移至我 github 的 ijkplayerDemo
      • Vlc(重量级) 国外的一个视频播放框架,体积比较大,一样需要自己动手编译.so,相比ijk,它功能强大一点,详情移至我 github 的 VlcDemo
    • 网页
      • 基于javaScript播放器 这个是我最初的尝试,在使用原生播放器的时候,通过正则替换文章内容的video标签,提取 src,然后组合 js 的播放器里面,能够自定义很多功能,例如:调节亮度和声音。
      • 直接使用腾讯x5浏览器内核 其实,我一直想做一个像微信打开公众平台文章那样的网页 webView,兼容性强,速度快且对视频的兼容十分好。这也是我最终的选择
2,线程层

       由于我网络请求这块没使用框架,所以线程的选用时 Thread + Handler 组合或 AsyncTask ,需要明确一点,AsyncTask 比 Thread + Handler 更耗资源,不过使用起来比较方便。

  • 数据列表类型的页面数据加载采用自定义的 AsyncTask 继承类来进行网络线程
  • 类似收藏、举报这类低数据流的网络请求采用 Thread + Handler 组合
  • 图片并发上传的类型,采用线程池进行
3,缓存层

       Android 的数据存储方式有5种,分别是 SharedPrefrences、File、SQLite、ContentProvider、NetWork。我采用的是 SharedPrefrences 和 File即是文件存储,其中

  • 标记性数据采用 SharedPrefrences,例如是否隐藏操作记录,用户名称等
  • 帖子列表、评论列表类大批量数据采用了File文件存储或sqlLite,原因是操作方便,只需要序列化和反序列化操作就能很方便地读出缓存并显示,这里要注意下你的bean类需要 imp 序列化接口。
4,网络层
  • 加载      全部是自己基于 HttpUrlConnection 封装的工具类。
  • 逻辑
    • 广播监听网络状态的变化以做对应操作
    • 加载前进行网络连接是否可达判断
    • 断网情况启用缓存
5,实现层

       帖子分享,我采用的 OneKeyShare SDK,之所以使用它,是因为它把绝大部分的平台的SDK分享接口都集成了,例如微信、QQ、QQ空间、新浪微博、知乎等等等等。

1) 注册与登录
  • 注册
    • 号码
      • 对只能是数字的检测
      • 手机号码 11 位的限制
      • 是否之前注册过的检查,这块要和服务器对接
    • 密码
      • 位数的限制,例如最少 6 位
      • 加密传输
    • 短信验证
      • 使用阿里大鱼服务商,服务端写好接口,移动端通过get或post手机号码过去,然后接口调用API发送
      • 重复发送的倒计时
  • 手机登录
  • 第三方登录
    • 微信登录 使用的是微信开放平台的 SDK,注意要先判断用户是否有安装微信
    • 新浪微博登陆 使用新浪开放平台的 SDK,新浪SDK会自动判断用户是否有安装新浪APP
   2) 发表帖子功能的实现
  • 编辑
    • 文字部分
      • 字数的限制 一定要限制用户帖子的输入字数的限制,一来减少服务器负担,二来避免恶意刷帖。
      • 内容过滤 要过滤掉某些敏感词,防止色情或其他内容出现
      • 用户位置获取 使用百度地图API
    • 图片部分
      • 选择
        • 张数的限制
        • 模仿了微信的图片选择器,采用GirdView加载,可以多张一起选择
        • 拍照
      • 显示
        • 命名采用:用户帐号+帖子id+图片下标,这样的好处是,完全能够唯一标识,且在看帖页面加载方便,组合链接简单。
        • 在发帖页面显示缩略图,提供有点击看大图和移除的功能
      • 图片服务器采用腾讯云- - -万象优图 1,具备缩放功能,方便生成、加载缩略图 2,可以自定义添加水印 3,鉴黄图,这是最重要的
    • 视频录制
      • 封装系统的 Camera + surface 录制,返回路径
      • 预览的时候直接用mediaPlayer + surface 播放
  • 上传
    • 注意大小,我是压缩控制在450K左右
      • 好处: 1, 加速上传速度 2, 加快用户在加载图片时的速度 3, 减少流量消耗
    • 先上传图片,在图片上传成功后,再开始上传文字内容,如果出错,图片可以直接覆盖,文字成功,图片失败时,帖子避免数据混乱
    • 采用线程池上传,一来方便控制并发数,二来方便回收内存
3) 帖子列表的显示
  • 控件选取

       选用了安卓5.0 的 SwipeRefreshLayout + RecyclerView,原因是 SwipeRefreshLayout 自身带有下拉刷新,最早的时候使用的是 PullToRefresh 开源项目。RecyclerView 重写onScroll() 就可以搞定加载更多,还有一个原因,RecyclerView 自带有瀑布流布局属性。        早之前我使用的是 LinearLayout 实现的,不断地 addView 再 remove,致命的缺点是内存消耗不合理。

  • 加载限制
    • 数据加载采用分批加载的方式进行,减轻服务器的并发请求负担和达到移动端的合理显示效果。
    • 帖子主要内容的加载应该只加载摘要,否则内容过多,会造成数据处理时间过长,显示慢。
4) 帖子详情页的显示
  • 代码结构
    • 由于帖子的类型有三种,这三种帖子除了内容部分布局不一样,评论布局是一样的,分享、删除等按钮也是一样的,当然,也可以自己通过接口改变评论布局。所以在类的集成方面,我采用了三个抽象类父类,子类只需要传进入自己布局、实现评论数据适配器 Adapter 即可。
      • 数据请求抽象类,含有请求方面的方法与属性
      • 数据组合抽象类,含有获取数据后进行组合的方法与属性
      • 数据显示抽象类,处理大部分的公共操作,例如评论列表的显示,分享等功能按钮,同时留有自定义布局的接口
  • 逻辑
    • 数据请求,根据点击跳转过来的帖子 id 来进行服务器数据请求。
    • 楼层评论
      • 判断是否已登录
      • 判断内容是否有表情
      • 判断是否是回复,回复就需要把被回复者的名称改颜色,并且添加点击事件
      • 采用 post 上传,因为采用get会有字节限制和中文乱码的问题,还一个是数据安全
      • 评论成功后再做应的UI更新,防止失败页面显示错乱
    • 点赞
      • 判断是否已经登录
      • 判断之前是否点过赞,否则就是撤销赞,这个操作需要在加载点赞账号的时候,保存到一个列表里面,例如 List 以作后续的判断。
      • 点赞成功后再做对应的UI更新,例如点赞图标变颜色等等
  • 布局

       采用的布局是 HeaderView + CommentView,HeaderView 用于显示帖子的所有内容含帖子点赞,CommentView 用来显示用户的评论

  • 加载顺序 1,请求服务器数据,判断该帖子是否有被删除 2,没被删除,那么先加载帖子的内容 3,最后再加载帖子的评论
5) 消息提醒

       消息提醒采用了极光推送的SDK实现

  • 以用户账号注册推送
  • 在服务端评论、点赞的接口代码处触发推送API
  • 通过广播的形式获取推送,显示消息提醒
6) 表情模块
  • 匹配
    • 以图片的名字组合其他标记符组合为 key,例如 [ ],资源id为value,放至常量区
    • 以正则匹配 key 的方式来判断是否有表情输入
  • 显示
    • 使用Spannable来将文字替换成drawable
    • 选择页面的显示采用 GirdView + viewPager 显示
7) 其他部分

       收藏、删除、举报,这些操作进行一次get操作,传递帖子的id给服务器,服务器处理完毕后,就做对应操作

  • 收藏,不能重复收藏,服务器做判断,返回信息
  • 删除,只能是帖主操作,删除成功后,返回主页刷新页面数据

       其他功能能的实现基本同上述。

8) 优化
  • 安装包
    • .so 动态库的添加,现在绝大部分手机已经支持 armeabi cpu 架构,所以只需要编译这种进去就够了,不是越多越好,越多,安装包会跟着变大!
    • 减少不必要的库引用
  • 内存
9) 使用的库

 第三方

自己派生

三、服务端架构概述

第二部分结束得有点匆忙,我真的很想把所有的东西都写下来,如果加上我一路遇到过的 bug 及其解决方法,估计还要写两天。主要原因是,有很多我记得已经不是太清楚了。

1,服务器
  • 集群 
    • 阿里云 Linux centos 6.5 操作系统,以ngnix 解析
    • 腾讯云- - - 万象优图,只用来存放图片
  • MySQL 数据库,MyISAM 与 InnoDB 引擎
  • php 语言开发接口
2,数据库引擎

       最初的我并没有采用 InnoDB,而是所有表都是全部是 MyISAM 。改用的原因是MyISAM 不支持事务InnoDB支持事务,而且社交类APP的数据库操作过多偏向于insertupdatedelete 这种操作如果涉及多表或单表互联操作的情况,为了避免数据写脏,所以使用事务。因为整个过程中若一条错误,便可以回滚到开始时的状态。

  • MyISAM 的查询速度比InnoDB快
  • 查询高发的表采用 MyISAM 引擎
  • 数据比较重要或多写操作的表采用InnoDB引擎
3,数据库设计

       对于数据库设计,不应该过多依赖范式,适度的冗余可以加快搜索速度,在服务器的配置还可以的情况下,可以采用冗余来解决查找慢的问题。

       常被 update 的字段,不应该出现在多张表,应该使用一张表,例如用户的名称,userName 这个肯定是会被经常改变的。否则在update数据的时候你要多张表更新!

  • 帖子有三种类型,对应三张表,文章独立一张表
  • 点赞一张表
  • 评论一张表
  • 收藏一张表
  • 信息提醒一张表
    • 用户消息的查看与否以及数目在移动端的显示,需要在消息表设置加上是否查看了的字段,可以解决以下几个问题:
      • 用户在卸载APP再安装时,不会造成查看混乱,例如之前看过的,又显示出来
      • 在每次用户进入APP的时候,可以很好地显示出新的消息,不会造成过于复杂的逻辑代码判断
  • 用户信息两张表
    • 账号信息一张,存账号、密码、注册时间、ip等
    • 基本信息一张,存签名、头像链接、背景图片链接等
4,接口
  • 数据传输格式 json array 或 字符串
  • 访问频繁的数据 架多一层 Redis,一定程度缓解高并发,需要服务器的内存支持,配置博可以参照我之前的博文点我
  • 代码
    • 封装一个自定义的 Redis 操作类
    • 封装一个基于事务的数据库连接类,方便使用
    • 封装一个用户信息类,专门用来处理用户的信息插入与获取

未完待续……

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张戈的专栏

WordPress集成底部滚动推荐条,让好文章不再被埋没

最新消息:目前该功能张戈博客已推出 WordPress 插件,欢迎安装使用!详细介绍=>> 这个功能最开始叫底部滚动公告条,部分 WordPress 主题集成自...

3209
来自专栏微信小程序开发

小程序中布局突然乱掉了,到底是怎么个情况?

就在上周,突然很多用户反馈,都说小小签到布局乱掉了(线上有四款小程序都收到这样的反馈,这里我就不广告了),经过客服反复沟通,找到了布局乱掉的必现条件: 1、IO...

39216
来自专栏IT派

利用python和百度地图API实现数据地图标注

地址:http://developer.baidu.com/map/jsdemo.htm#c1_19

1292
来自专栏一“技”之长

标签之美三——超链接的嵌入 原

通常的超链接有两种方式,一种是链接到另一个文件,另一种是链接到当前文件的某个位置。这两种方式都是通过<a></a>标签来创建,其中href属性用来指定链接的目标...

852
来自专栏葡萄城控件技术团队

HTML5 & CSS3初学者指南(1) – 编写第一行代码

介绍 网络时代已经到来。现在对人们来说,每天上网冲浪已经成为一种最为常见的行为。 在网页浏览器中输入一段文本地址,就像http://www.codeprojec...

1856
来自专栏前端大白专栏

关于富文本编辑器

2666
来自专栏张戈的专栏

利用placeholder属性来添加输入框默认文字提示,提高用户体验

这个是我老早就在用的方法,本不打算分享,因为网上随便都能搜得到,感觉没有分享的必要。鉴于中国博客联盟有朋友问到了这问题,所以还是简单的整理下,希望能帮到部分不了...

3099
来自专栏ROBOTEDU

828D数控与HMI通讯

HMI与828D系统之间的通信 ? 1. 设置828D X130(在屏幕后面)工厂网络IP地址 ? 上图,在诊断菜单,选择”TCP/IP总线”.选择右侧的”TC...

2838
来自专栏FreeBuf

没想到你是这样的Linux | 终端下有趣的命令合集

前言 刚开始接触Linux的我们,肯定认为Linux系统就是那种枯燥的终端界面。然而实际上Linux下的终端还是有很多种有趣的玩法~~ toilet 简介 to...

3825
来自专栏腾讯社交用户体验设计

What You See Is What You Get

1163

扫码关注云+社区