社會化登入分享-原始碼解析

Tsy遠發表於2017-09-22

本篇文章具體對該社會化SDK進行了原始碼解析。增加大家對該SDK設計的理解,方便大家自己fork,持續整合開發。

具體程式碼專案Github地址:github.com/tsy12321/So…

0 系列文章

系列一 Android SDK的二次封裝和使用
系列二 原始碼解析
系列三 微信SDK接入
系列四 QQ SDK接入
系列五 新浪微博 SDK接入

1 前言

整個SDK的設計都是基於抽象介面的實現,比如不同的平臺都基於SSOHandler,不同的分享媒介都基於IShareMedia,所有config資訊儲存在靜態Map中。

SDK封裝的方式是本身的實現程式碼封裝單獨的sdk,裡面實現各個平臺的登入分享實現程式碼,需要哪個平臺直接搭配那個平臺的SDK即可使用。(後面如果程式碼變多可以考慮將抽象的封裝單獨SDK,不同平臺的實現也封裝一個,這樣搭配平臺就可以是:本身SocialSDK+平臺SDK+平臺實現SDK)

2 不同平臺配置資訊的儲存

所有配置資訊儲存在PlatformConfig.configs中,是一個靜態Map

public class PlatformConfig {

    public static Map<PlatformType, PlatformConfig.Platform> configs = new HashMap();

    static {
        configs.put(PlatformType.WEIXIN, new PlatformConfig.Weixin(PlatformType.WEIXIN));
        configs.put(PlatformType.WEIXIN_CIRCLE, new PlatformConfig.Weixin(PlatformType.WEIXIN_CIRCLE));
    }
    ...
}複製程式碼

然後在專案入口(Application或者入口Activity)要求使用者初始化配置資訊。

PlatformConfig.setWeixin(WX_APPID, WX_APPSECRET);複製程式碼

裡面具體實現即是將配置資訊儲存在不同的config裡。不同平臺的config都實現PlatformConfig.Platform介面,然後在自己裡面根據配置資訊不同儲存不同資訊。

public interface Platform {
        PlatformType getName();
        boolean isConfigured();
    }

    //微信
    public static class Weixin implements PlatformConfig.Platform {
        private final PlatformType media;
        public String appId = null;
        public String appSecret = null;

        public PlatformType getName() {
            return this.media;
        }

        public Weixin(PlatformType var1) {
            this.media = var1;
        }

        public boolean isConfigured() {
            return !TextUtils.isEmpty(this.appId) && !TextUtils.isEmpty(this.appSecret);
        }
    }

    /**
     * 設定微信配置資訊
     * @param appId
     * @param appSecret
     */
    public static void setWeixin(String appId, String appSecret) {
        PlatformConfig.Weixin weixin = (PlatformConfig.Weixin)configs.get(PlatformType.WEIXIN);
        weixin.appId = appId;
        weixin.appSecret = appSecret;

        //微信朋友圈也用相同的配置資訊
        PlatformConfig.Weixin weixin_circle = (PlatformConfig.Weixin)configs.get(PlatformType.WEIXIN_CIRCLE);
        weixin_circle.appId = appId;
        weixin_circle.appSecret = appSecret;
    }複製程式碼

3 不同平臺登入、分享的實現

所有平臺都會繼承抽象類SSOHandler,抽象類中有authorize、share等介面,在各自平臺實現的Handler中根據不同平臺接入文件不同各自實現。統一結果回撥AuthListerner或者ShareListener。

類圖如下:

SSOHandler類圖
SSOHandler類圖

SSOHandler程式碼:

public abstract class SSOHandler {

    /**
     * 初始化
     * @param context
     * @param config 配置資訊
     */
    public void onCreate(Context context, PlatformConfig.Platform config) {

    }

    /**
     * 登入授權
     * @param authListener 授權回撥
     */
    public void authorize(AuthListener authListener) {

    }

    /**
     * 分享
     * @param shareMedia 分享內容
     * @param shareListener 分享回撥
     */
    public void share(IShareMedia shareMedia, ShareListener shareListener) {

    }

    /**
     * 是否安裝
     * @return
     */
    public boolean isInstall() {
        return true;
    }
}複製程式碼

各自的平臺Handler程式碼即需要根據不同文件去實現。

4 多種分享媒介的實現

現在分享支援文字分享、圖片分享、音樂分享、視訊分享、網頁分享。

5個分享都會實現一個實體類,裡面定義各個媒介需要的元素。比如文字分享需要分享文字,音樂分享需要音樂的地址、分享內容、縮圖等。

類圖如下:

分享媒介類圖
分享媒介類圖

呼叫分享介面時根據需要分享的媒介各自實體化媒介類。


//分享媒介 後面有詳細介紹
ShareWebMedia shareMedia = new ShareWebMedia();
shareMedia.setTitle("分享網頁測試");
shareMedia.setDescription("分享網頁測試");
shareMedia.setWebPageUrl("http://www.baidu.com");
shareMedia.setThumb(BitmapUtils.readBitMap(getApplicationContext(), R.mipmap.ic_launcher));複製程式碼

然後傳入分享介面:

/**
     * 分享
     * @param shareMedia 分享內容
     * @param shareListener 分享回撥
     */
    public void share(IShareMedia shareMedia, ShareListener shareListener) {

    }複製程式碼

在具體實現的share函式中判斷media具體是哪個,然後呼叫相應平臺的分享sdk

@Override
    public void share(IShareMedia shareMedia, ShareListener shareListener) {


        if(shareMedia instanceof ShareWebMedia) {       //網頁分享
            ...
        } else if(shareMedia instanceof ShareTextMedia) {   //文字分享
            ...
        } else if(shareMedia instanceof ShareImageMedia) {  //圖片分享
            ...
        } else if(shareMedia instanceof ShareMusicMedia) {  //音樂分享
            ...
        } else if(shareMedia instanceof ShareVideoMedia) {      //視訊分享
            ...
        } else {
            if(this.mShareListener != null) {
                this.mShareListener.onError(this.mConfig.getName(), "shareMedia error");
            }
            return ;
        }

       ...複製程式碼

5 結果回撥通知

由於不同平臺的回撥方式不同,比如微信是必須實現wxapi.WXEntryActivity 在這個activity實現回撥。QQ是在onActivityResult中實現結果回撥。其實原理一樣。

在回撥入口處重寫(WXEntryActivity)或者呼叫(onActivityResult),然後將回撥處理放到不同平臺的Handler中處理,最後呼叫初始傳入的AuthListener或者ShareListener回撥結果。

結尾

整體的實現很簡單,這樣的設計也更加容易擴充套件多個平臺。本篇就醬紫了,下篇會介紹不同平臺的接入實現和注意點。

相關文章