本篇文章具体对该社会化SDK进行了源码解析。增加大家对该SDK设计的理解,方便大家自己fork,持续集成开发。
0 系列文章
1 前言
整个SDK的设计都是基于抽象接口的实现,比如不同的平台都基于SSOHandler,不同的分享媒介都基于IShareMedia,所有config信息保存在静态Map中。
SDK封装的方式是本身的实现代码封装单独的sdk,里面实现各个平台的登录分享实现代码,需要哪个平台直接搭配那个平台的SDK即可使用。(后面如果代码变多可以考虑将抽象的封装单独SDK,不同平台的实现也封装一个,这样搭配平台就可以是:本身SocialSDK+平台SDK+平台实现SDK)
2 不同平台配置信息的保存
所有配置信息保存在PlatformConfig.configs中,是一个静态Map
public class PlatformConfig {
public static Map 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回调结果。
结尾
整体的实现很简单,这样的设计也更加容易扩展多个平台。本篇就酱紫了,下篇会介绍不同平台的接入实现和注意点。