標籤:技術架構 應用 android
Android應用內社區SDK技術架構淺析應用內微社區是什麼 ?
一、以友盟微社區為例
簡單來說,友盟的微社區就是一款協助開發人員在應用中快速搭建一個社區( 類似於新浪微博、朋友圈 )的產品。在很多應用中,開發商往往都會需要一個使用者之間以及使用者與開發商之間互動的社區,使用者往往又會在社區裡選擇贊、評論、關注、轉寄、發帖等各種互動方式。但是開發一個社交系統可不是那麼容易的一件事,複雜的使用者關係、訊息流程、伺服器架構等等都是棘手的問題,更重要的是大家都是重複地勞動!每個開發商需要這些功能的時候都需要從頭開始構建這麼一個開發成本很高的社交系統。友盟為瞭解決這些問題推出了友盟微社區SDK (內測階段) 這款產品,它可以讓你以SDK整合的方式快速的構建一個社區,大大提高了生產力和使用者活躍度。
1.1 友盟微社區的特點
- UI開源;
- 可作為SDK嵌入已有應用 ;
- 可一鍵產生獨立APP;
- 賬戶系統、圖片載入等核心組件可定製;
- 先進的anti-spam,自動肅清垃圾資訊;
3、圖4是雲圖TV的整合效果。
二、技術架構
從項目結構上來說,友盟微社區SDK可以簡單分為如下三層:
UI層 (開源)
UI層對外開放,目的是讓使用者能夠定製友盟微社區的UI效果,使微社區SDK能夠很自然的融入到使用者的App中。
商務邏輯層
商務邏輯層會通過一個統一的介面向UI層提供資料資料請求等功能,比如擷取緩衝的feed、好友名單等,因此商務邏輯層對於使用者來說是一個資料操作介面,通過這個介面使用者能夠與SDK 核心層進行一些資料方面的操作。
核心層
核心層則包含了友盟SDK的核心系統抽象,比如賬戶系統、推送、資料庫、網路操作等,這一層對外封閉,使用者可以通過一些介面與核心層進行互動。而核心層定義的抽象使得使用者可以很方便的實現定製化,即自己實現抽象介面,然後將具體的實現注入到友盟微社區中,從而使自己的子系統替換掉微社區中的預設實現 (下文會給出樣本 )。
2-1所示,友盟微社區SDK層次分明,通過這三個層次的隔離,使得使用者既可以自訂最外層的UI效果,也對外隱藏了商務邏輯層、核心層的實現細節。而核心層定義的子系統抽象,使得使用者可以注入自己的實現,保證了整個微社區SDK的靈活性、擴充性。
圖 2-1 洋蔥結構圖
簡單來說,就是使用者在UI層通過邏輯層暴露的通用介面來操作友盟微社區SDK,從封閉的核心系統中擷取、儲存資料以及其他的相關操作。階層 2-2所示。
圖 2-2 階層圖
圖2-1、2-2都顯示了友盟微社區SDK是通過不同的層次來分離職責,是一個較為典型的架構形式。對於使用者來說,最關心的莫過於可定製化。UI層開放源碼,自然可以通過修改代碼來實現。其他的定製化使用者就需要依賴注入來實現。友盟微社區SDK內部依賴於抽象,而不依賴於具體實現,並且使用者可以注入具體實現。也就是說使用者可以根據我們的抽象介面實現自己的子系統,然後注入到SDK內部,SDK此時就會使用使用者注入的實現,這樣就達到了子系統替換的效果,也就是我們說的定製化。
三、友盟微社區的定製化3.1 如何滿足定製化 ?
那麼如何來實現定製化呢? 友盟微社區SDK內部定義了一些抽象,比如Loginable、Pushable、ImageLoader來分別代表登入系統介面、推送介面、圖片載入介面,每種介面都有一個SDKManager來進行管理。比如管理登入子系統的就是LoginSDKManager,使用者可以往這個Manager裡面添加、移除具體的登入系統實現,然後通過useThis函數來指定使用某個具體的實現(SDK Manager裡面可能有多個實現 )。結構圖 3-1所示 。
圖 3-1
SDK Manager是一個泛型類,類型T就代表了介面類型,比如上述的Loginable等。通過泛型我們就可以將這些通用的添加、移除實現等操作抽象化,避免重複代碼。代碼如下所示:
public abstract class SDKManager<T> { // 泛型Map private Map<String, T> mImplMap = new HashMap<String, T>(); // 要使用的實現的key private String mCurrentKey = ""; public void addImpl(String key, T impl) { mImplMap.put(mCurrentKey, impl); } public void removeImpl(String key) { mImplMap.remove(mCurrentKey); } public void useThis(String key) { mCurrentKey = key; } public T getCurrentImpl() { return mImplMap.get(mCurrentKey); } public void addAndUse(T impl) { if (impl == null) { return; } mCurrentKey = impl.getClass().getSimpleName(); mImplMap.put(mCurrentKey, impl); }}
代碼很簡單,就是在SDK Manager內部維護了一個Map,key是使用者為這個實現指定的一個字串值,value就是具體的實現。使用者可以通過這個key來移除實現,更常用的是我們需要調用useThis(String key)介面來指定使用某個具體的實現。
我們並沒有直接使用SDKManager,因為它是一個抽象泛型類,因此我們定義了一些子類來對不同的實現進行管理,這些子類都是單例類,例如LoginSDKManager,代碼如下所示。
public final class LoginSDKManager extends SDKManager<Loginable> { // 單例對象 static LoginSDKManager sInstance = new LoginSDKManager(); private LoginSDKManager() { } // 擷取單例對象 public static LoginSDKManager getInstance() { return sInstance; }}
在使用者需要對登入系統進行管理時,通過LoginSDKManager.getInstance()就可以擷取到負責管理登入系統的SDK Manager,此時使用者可以通過addImpl(String key, T impl)、useThis(String key)等介面對登入系統進行管理,這就就可以靈活使用使用者自訂的子系統。
3.2 樣本
下面還是以一個樣本來說明問題吧。
在與使用者溝通的過程中,我們發現登入模組是使用者自訂機率最高的子系統。通常情況下,使用者可能有自己的賬戶系統或者使用了第三方登入( 比如友盟社會化組件 ),此時使用者就不需要友盟微社區SDK中附帶的登入實現,完全依賴自己的賬戶系統或者其他第三方登入SDK來實現一個登入系統。下面我們就以實現登入系統 ( 其他子系統的自訂原理一樣 ) 來示範自訂過程。
在開始之前,我們需要對登入的抽象介面Loginable進行瞭解。代碼如下所示:
public interface Loginable { public void login(); public void logout(); public boolean isLogined();}
- login() : 登入函數,使用者需要在登入成功後將使用者資訊回調給友盟微社區SDK (具體過程可以參考友盟微社區整合文檔);
- logout() : 登出函數,登出使用者的登入即可;
- isLogined() : 使用者是否登入,返回true表示已登入,否則為未登入。
微社區SDK內部通過抽象了幾個簡單介面來定義登入模組的功能,使用者通過實現這幾個函數即可定製自己的登入系統,最後將實現諸如到友盟微社區SDK即可。例如,如果你的應用中已經有了自己的賬戶系統邏輯,你可以在Loginable的幾個函數中通過調用你的賬戶系統邏輯實現這幾個功能;如果你使用了友盟社會化組件 ( 注意 : 雖然友盟微社區SDK的登入模組使用的是友盟社會化組件,但它們的jar檔案並不是一致的,因此不管你使用其中哪一個實現,都需要更新所有與登入相關的jar檔案。 ),那麼你可以通過友盟社會化組件的登入、登出功能實現對應的功能,例如你可以在login()函數中調用UMSocialService對象的doOauthVerify(Context context , SHARE_MEDIA platform , UMAuthListener listener)介面來實現登入。一句話概括就是 : 自訂一個實現了Loginable介面的類,在這個類的各個函數中調用你原有的登入、登出、判斷是否已登入的函數來實現對應的功能。實現了登入類之後,通過LoginSDKManager的addImpl(String key, Loginable impl)來將該實現注入到友盟微社區SDK中,最後通過LoginSDKManager的useThis(String key)函數來指定要使用的登入實現,這個key就是addImpl(String key, Loginable impl)中設定的key。
自訂登入類範例程式碼如下 :
/** * 友盟社會化組件的登入實現,這裡可以替換成自己的賬戶系統、第三方登入等,實現幾個介面函數即可。 */public class SocialLoginImpl implements Loginable { @Override public void login() { // 登入的具體實現,可以調用你自己的登入代碼或者第三方SDK的登入函數 } @Override public void logout() { // 登出的具體實現,可以調用你自己的登入代碼或者第三方SDK的登入函數 } @Override public boolean isLogined() { // 檢測是否登入 return true /* 代碼省略 */; }}
注入登入實現 :
// 登入系統管理器LoginSDKManager loginMgr = LoginSDKManager.getInstance() ;// keyString clzKey = SocialLoginImpl.class.getName() ;// 注入實現loginMgr.addImpl(clzKey, new SocialLoginImpl());// 指定使用的具體實現loginMgr.useThis(clzKey);
為了更簡單,這個過程被我們封裝到一個函數中,使用的代碼最後簡化為 :
// 一行代碼搞定!這個函數封裝了上述所有的代碼。LoginSDKManager.getInstance().addAndUse(new SocialLoginImpl()) ;
通過這幾步,登入系統就注入到微社區SDK中了。當友盟微社區需要登入時,微社區SDK就會通過LoginSDKManager的getCurrentImpl()函數擷取使用者指定的登入實現,然後觸發對應的login()函數,此時就會執行你的登入流程。登入成功之後,通過login()函數的回調listener ( 這個簡單樣本中沒有給出該listener, 具體可參考 友盟微社區使用已有賬戶系統 ) 將使用者資訊傳回給友盟SDK,就完成了整個登入過程。
雜談
目前友盟微社區SDK還處在內測階段 ( 友盟微社區內測申請地址,不過已經可以投入使用。已經有一部分整合了友盟微社區的App上線,並且運行良好。希望本文能有開發第三方Android SDK的同學一些協助,讓開發中的坑更少一些。
Android應用內社區SDK技術架構淺析