社會化登錄分享-源碼解析

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

具體代碼項目Github地址:https://github.com/tsy12321/SocialSDKAndroid

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代碼:

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回調結果。

結尾

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容