android 第三方社区,从友盟微社区看Android第三方SDK架构实践
原標題:從友盟微社區看Android第三方SDK架構實踐
開發Android第三方SDK說難不難,但說簡單也不簡單,要開發一個給很多人使用的第三方SDK,如何在保證穩定性的同時,增強SDK的靈活性,讓開發者能自由定制UI層、替換子系統,這是一個值得思考的問題。為了解決這個問題,開發第三方SDK必須要有良好的應用架構。本文就分享一下我在開發友盟微社區SDK時在架構方面的一些想法。
友盟的微社區是一款幫助開發者在應用中快速搭建一個社區(類似于新浪微博、朋友圈),目前正在內測當中。
技術架構
從項目結構上來說,友盟微社區SDK可以簡單分為如下三層。
UI層(開源)。UI層對外開放,目的是讓用戶能夠定制微社區的UI效果,使微社區SDK能夠很自然的融入到用戶的App中。
業務邏輯層。業務邏輯層會通過一個統一的接口向UI層提供數據請求等功能,比如獲取緩存的feed、好友列表等,因此業務邏輯層對于用戶來說是一個數據操作接口,通過這個接口用戶能夠與SDK核心層進行一些數據方面的操作。
核心層。核心層則包含了友盟SDK的核心系統抽象,比如賬戶系統、推送、數據庫、網絡操作等,這一層對外封閉,用戶可以通過一些接口與核心層進行交互。而核心層定義的抽象使得用戶可以很方便的實現定制化,即自己實現抽象接口,然后將具體的實現注入到微社區中,從而使自己的子系統替換掉微社區中的默認實現。
如圖1所示,SDK層次非常分明,通過這三個層次的隔離,使得用戶既可以自定義最外層的UI效果,也對外隱藏了業務邏輯層、核心層的實現細節。而核心層定義的子系統抽象,使得用戶可以注入自己的實現,保證了整個微社區SDK的靈活性、擴展性。
圖1 洋蔥結構圖
簡單來說,就是用戶在UI層通過邏輯層暴露的通用接口來操作SDK,從封閉的核心系統中獲取、存儲數據以及其他的相關操作。層次結構如圖2所示。
圖2 層次結構圖
圖1、圖2都顯示了SDK是通過不同的層次來分離職責,是一個較為典型的架構形式。對于用戶來說,最關心的莫過于可定制化。UI層開放源碼,自然可以通過修改代碼來實現。其他的定制化用戶就需要依賴注入來實現。微社區SDK內部依賴于抽象,而不依賴于具體實現,并且用戶可以注入具體實現。也就是說用戶可以根據我們的抽象接口實現自己的子系統,然后注入到SDK內部,SDK此時就會使用用戶注入的實現,這樣就達到了子系統替換的效果,也就是我們說的定制化。
友盟微社區的定制化
如何滿足定制化?
那么如何來實現定制化呢?友盟微社區SDK內部定義了一些抽象,比如Loginable、Pushable、ImageLoader來分別代表登錄系統接口、推送接口、圖片加載接口,每種接口都有一個SDKManager來進行管理。比如管理登錄子系統的就是LoginSDKManager,用戶可以往這個Manager里面添加、移除具體的登錄系統實現,然后通過useThis函數來指定使用某個具體的實現(SDK Manager里面可能有多個實現)。結構圖如圖3所示。
圖3 LoginSDKManager功能
SDK Manager是一個泛型類,類型T就代表了接口類型,比如上述的Loginable等。通過泛型我們就可以將這些通用的添加、移除實現等操作抽象化,避免重復代碼。代碼如下所示:
public abstract class SDKManager{
// 泛型Map
private MapmImplMap = new HashMap();
// 要使用的實現的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);
}
}
代碼很簡單,就是在SDK Manager內部維護了一個Map,key是用戶為這個實現指定的一個字符串值,value就是具體的實現。用戶可以通過這個key來移除實現,更常用的是我們需要調用useThis(String key)接口來指定使用某個具體的實現。
我們并沒有直接使用SDKManager,因為它是一個抽象泛型類,因此我們定義了一些子類來對不同的實現進行管理,這些子類都是單例類,例如LoginSDKManager,代碼如下所示。
public final class LoginSDKManager extends SDKManager{
// 單例對象
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)等接口對登錄系統進行管理,這就可以靈活使用用戶自定義的子系統。
示例
下面還是以一個示例來說明問題吧。在與用戶溝通的過程中,我們發現登錄模塊是用戶自定義概率最高的子系統。通常情況下,用戶可能有自己的賬戶系統或者使用了第三方登錄,此時用戶就不需要友盟微社區SDK中附帶的登錄實現,完全依賴自己的賬戶系統或者其他第三方登錄SDK來實現一個登錄系統。下面我們就以實現登錄系統(其他子系統的自定義原理一樣)來演示自定義過程。在開始之前,我們需要對登錄的抽象接口Loginable進行了解。代碼如下所示:
public interface Loginable {
public void login();
public void logout();
public boolean isLogined();
}
login():登錄函數,用戶需要在登錄成功后將用戶信息回調給友盟微社區SDK(具體過程可以參考友微社區集成文檔 http://dev.umeng.com/wsq/android/detail-integration#1);
logout():登出函數,注銷用戶的登錄即可;
isLogined():用戶是否登錄,返回true表示已登錄,否則為未登錄。
微社區SDK內部通過抽象了幾個簡單接口來定義登錄模塊的功能,用戶通過實現這幾個函數即可定制自己的登錄系統,最后將實現注入到SDK即可。例如,如果你的應用中已經有了自己的賬戶系統邏輯,你可以在Loginable的幾個函數中通過調用你的賬戶系統邏輯實現這幾個功能;如果你使用了友盟社會化組件那么你可以通過該社會化組件的登錄、登出功能實現對應的功能,例如你可以在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() ;
// key
String clzKey = SocialLoginImpl.class.getName() ;
// 注入實現
loginMgr.addImpl(clzKey, new SocialLoginImpl());
// 指定使用的具體實現
loginMgr.useThis(clzKey);
為了更簡單,這個過程被我們封裝到一個函數中,使用的代碼最后簡化為 :
// 一行代碼搞定!這個函數封裝了上述所有的代碼。
LoginSDKManager.getInstance().addAndUse(new SocialLoginImpl()) ;
通過這幾步,登錄系統就被替換掉了。當微社區需要登錄時,微社區SDK就會通過LoginSDKManager獲取當前使用的登錄實現,然后觸發login()函數,此時就會執行你的登錄代碼了。登錄成功之后,通過login()函數的回調listener(這個簡單示例中沒有給出該listener,具體可參考友盟微社區使用已有賬戶系統)將用戶信息傳回給友盟SDK,就完成了整個登錄過程。
目前友盟微社區SDK還處在內測階段(內測申請地址:http://wsq.umeng.com/),不過已經可以投入使用。已經有一部分集成了友盟微社區的App上線,并且運行良好。希望本文能有開發第三方Android SDK的同學一些幫助,讓開發中的坑更少一些。
本文作者:何紅輝,Android工程師,現任職于友盟。樂于分享,熱愛開源,開源項目有AndroidEventBus、android-tech-frontier、Android源碼設計模式分析。
CSDN博客:http://blog.csdn.net/bboyfeiyu,GitHub
主頁:https://github.com/bboyfeiyu
責任編輯:
總結
以上是生活随笔為你收集整理的android 第三方社区,从友盟微社区看Android第三方SDK架构实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓自定义view仿小米商城购物车动画
- 下一篇: 大数据开发超高频面试题!大厂面试必看!包