社会化登录分享-源码解析

本篇文章具体对该社会化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回调结果。

结尾

整体的实现很简单,这样的设计也更加容易扩展多个平台。本篇就酱紫了,下篇会介绍不同平台的接入实现和注意点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容