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