從友盟微社區看Android第三方SDK架構實踐【轉載】

來源:互聯網
上載者:User

標籤:

從友盟微社區看Android第三方SDK架構實踐【轉載】

“先寫在前面吧,本來想通過連結來轉載這篇文章,發現沒找到有相關的按鈕。上網查了一下,都說部落格園沒有這功能。我在部落格園也有一段時間了,鼓勵原創是必須的,不過適當的轉載也算是一種將有價值的文章進行分享的方式,不知道以後會不會支援呢!”

 

原文連結:http://www.csdn.net/article/2015-05-08/2824648-micro-community  摘要:第三方SDK的開發需要考慮很多因素,比如穩定性、靈活性等,並且還要做到能讓開發人員能自由定製UI層、替換子系統。本文以友盟微社區為例,詳細講解了在開發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<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);

  }

}

代碼很簡單,就是在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)等介面對登入系統進行管理,這就可以靈活使用使用者自訂的子系統。

樣本

下面還是以一個樣本來說明問題吧。在與使用者溝通的過程中,我們發現登入模組是使用者自訂機率最高的子系統。通常情況下,使用者可能有自己的賬戶系統或者使用了第三方登入,此時使用者就不需要友盟微社區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第三方SDK架構實踐【轉載】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.