(本博客為原創:http://www.cnblogs.com/linguanh/)
前言:
這算是我的第一個 完完全全 由自己開發的
社交類安卓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
- Ijkplayer(
-
網頁
- 基於javaScript播放器
這個是我最初的嘗試,在使用原生播放器的時候,通過正則替換文章內容的video標簽,提取 src,然后組合 js 的播放器里面,能夠自定義很多功能,例如:調節亮度和聲音。
- 直接使用騰訊x5瀏覽器內核
其實,我一直想做一個像微信打開公眾平台文章那樣的網頁 webView,兼容性強,速度快且對視頻的兼容十分好。這也是我最終的選擇
- 基於javaScript播放器
-
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, 減少流量消耗
- 好處:
- 先上傳圖片,在圖片上傳成功后,再開始上傳文字內容,如果出錯,圖片可以直接覆蓋,文字成功,圖片失敗時,帖子避免數據混亂
- 采用
線程池
上傳,一來方便控制並發數,二來方便回收內存
- 注意大小,我是壓縮控制在450K左右
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的數據庫操作過多偏向於insert
、update
、delete
這種操作如果涉及多表或單表互聯操作的情況,為了避免數據寫臟,所以使用事務。因為整個過程中若一條錯誤,便可以回滾到開始時的狀態。
- MyISAM 的查詢速度比InnoDB快
- 查詢高發的表采用 MyISAM 引擎
- 數據比較重要或多
寫操作
的表采用InnoDB引擎
3,數據庫設計
對於數據庫設計,不應該過多依賴范式,適度的冗余
可以加快搜索速度,在服務器的配置還可以的情況下,可以采用冗余來解決查找慢的問題。
常被 update
的字段,不應該出現在多張表,應該使用一張表,例如用戶的名稱,userName 這個肯定是會被經常改變的。否則在update數據的時候你要多張表更新!
- 帖子有三種類型,對應三張表,文章獨立一張表
- 點贊一張表
- 評論一張表
- 收藏一張表
- 信息提醒一張表
- 用戶消息的查看與否以及數目在移動端的顯示,需要在消息表設置加上是否查看了的字段,可以解決以下幾個問題:
- 用戶在卸載APP再安裝時,不會造成查看混亂,例如之前看過的,又顯示出來
- 在每次用戶進入APP的時候,可以很好地顯示出新的消息,不會造成過於復雜的邏輯代碼判斷
- 用戶消息的查看與否以及數目在移動端的顯示,需要在消息表設置加上是否查看了的字段,可以解決以下幾個問題:
- 用戶信息兩張表
- 賬號信息一張,存賬號、密碼、注冊時間、ip等
- 基本信息一張,存簽名、頭像鏈接、背景圖片鏈接等
4,接口
- 數據傳輸格式
json array 或 字符串 - 訪問頻繁的數據
架多一層 Redis,一定程度緩解高並發,需要服務器的內存支持,配置博可以參照我之前的博文點我 - 代碼
- 封裝一個自定義的 Redis 操作類
- 封裝一個基於事務的數據庫連接類,方便使用
- 封裝一個用戶信息類,專門用來處理用戶的信息插入與獲取