69.源码解析:友盟分享
1.分享的主持类
public class SharePresenter {
//QQ分享帐号
private final static String QQ_AppID = "***";
private final static String QQ_AppKey = "***";
//微信分享帐号
private final static String WX_AppID = "***";
private final static String WX_AppKey = "***";
// 整个平台的Controller, 负责管理整个SDK的配置、操作等处理
public static UMSocialService mController = UMServiceFactory.getUMSocialService("test");
private static void init(Activity activity) {
initPlatforms(activity);
initShareContent(activity);
}
/**
* 配置平台
*/
private static void initPlatforms(Activity activity) {
// 添加新浪SSO授权
mController.getConfig().setSsoHandler(new SinaSsoHandler());
// 添加QQ支持, 并且设置QQ分享内容的target url
UMQQSsoHandler qqSsoHandler = new UMQQSsoHandler(activity,QQ_AppID,QQ_AppKey);
qqSsoHandler.addToSocialSDK();
// 添加QZone平台
QZoneSsoHandler qZoneSsoHandler = new QZoneSsoHandler(activity,QQ_AppID,QQ_AppKey);
qZoneSsoHandler.addToSocialSDK();
// 添加微信平台
UMWXHandler wxHandler = new UMWXHandler(activity, WX_AppID, WX_AppKey);
wxHandler.addToSocialSDK();
// 支持微信朋友圈
UMWXHandler wxCircleHandler = new UMWXHandler(activity, WX_AppID, WX_AppKey);
wxCircleHandler.setToCircle(true);
wxCircleHandler.addToSocialSDK();
}
/**
* 配置分享内容
*/
private static void initShareContent(Activity activity) {
UMImage urlImage = new UMImage(activity,"http://www.che.com/upload/system/d95aa9d7-7980-4f61-84e1-3c28d320d051.png");
// 设置QQ空间分享内容
QZoneShareContent qzone = new QZoneShareContent();
qzone.setTitle("车城网分享测试");
qzone.setShareContent("买好车,上车城!");
qzone.setTargetUrl("http://www.che.com");
mController.setShareMedia(qzone);
// 设置QQ好友分享内容
QQShareContent qq = new QQShareContent();
qq.setTitle("车城网分享测试");
qq.setShareContent("买好车,上车城!");
qq.setTargetUrl("http://www.che.com");
mController.setShareMedia(qq);
//设置新浪微博分享内容
SinaShareContent sina = new SinaShareContent();
sina.setShareContent("买好车,上车城!车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
sina.setShareImage(new UMImage(activity, R.drawable.ic_main));
mController.setShareMedia(sina);
//设置微信好友分享内容
WeiXinShareContent wx = new WeiXinShareContent();
wx.setShareContent("车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
wx.setTitle("买好车,上车城!");
wx.setTargetUrl("http://www.che.com");
wx.setShareMedia(urlImage);
mController.setShareMedia(wx);
// 设置朋友圈分享的内容
CircleShareContent circle = new CircleShareContent();
circle.setShareContent("车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
circle.setTitle("买好车,上车城!");
circle.setTargetUrl("http://www.che.com");
circle.setShareMedia(urlImage);
mController.setShareMedia(circle);
}
/**
* 弹出对话框,分享到微信、QQ、新浪等
*/
public static void share(Activity activity) {
init(activity);
mController.getConfig().setPlatforms(SHARE_MEDIA.WEIXIN,SHARE_MEDIA.WEIXIN_CIRCLE,SHARE_MEDIA.SINA);
mController.openShare(activity, false);
}
/**
* 弹出对话框,分享到微信、QQ、新浪等
*/
public static void share(Activity activity,String shareCarName,String sharePrice,String shareImageUrl,String shareUrl) {
LogUtil.e("shareCarName"+shareCarName+"\tshareImageUrl="+shareImageUrl+"\tshareUrl="+shareUrl);
initPlatforms(activity);
initShareContent(activity, shareCarName, sharePrice, shareImageUrl, shareUrl);
mController.getConfig().setPlatforms(SHARE_MEDIA.WEIXIN,SHARE_MEDIA.WEIXIN_CIRCLE,SHARE_MEDIA.SINA);
mController.openShare(activity, false);
}
/**
* 配置分享内容
*/
private static void initShareContent(Activity activity,String shareCarName,String sharePrice,String shareImageUrl,String shareUrl) {
shareImageUrl="http://www.che.com/upload/system/d95aa9d7-7980-4f61-84e1-3c28d320d051.png";
UMImage urlImage = new UMImage(activity,shareImageUrl);
//设置新浪微博分享内容
SinaShareContent sina = new SinaShareContent();
sina.setShareContent("买好车,上车城!车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
sina.setShareImage(new UMImage(activity, R.drawable.isloading));
mController.setShareMedia(sina);
//设置微信好友分享内容
WeiXinShareContent wx = new WeiXinShareContent();
wx.setShareContent("车城交易价: "+sharePrice+",来车城分期贷款:支持0首付,车险办理,代办过户、延保");
wx.setTitle(shareCarName);
wx.setTargetUrl(shareUrl);
wx.setShareMedia(urlImage);
mController.setShareMedia(wx);
// 设置朋友圈分享的内容
CircleShareContent circle = new CircleShareContent();
circle.setShareContent("车城交易价: "+sharePrice+",来车城分期贷款:支持0首付,车险办理,代办过户、延保");
circle.setTitle(shareCarName);
circle.setTargetUrl(shareUrl);
circle.setShareMedia(urlImage);
mController.setShareMedia(circle);
}
}
2.第一步:配置平台
// 添加微信平台
UMWXHandler wxHandler = new UMWXHandler(activity, WX_AppID, WX_AppKey);
wxHandler.addToSocialSDK();
首先,创建UMWXHandler:
public UMWXHandler(Context context, String appid, String secret) {
this.THUMB_SIZE = 150;
this.THUMB_LIMIT = '耀';
this.TITLE_LIMIT = 512;
this.DESCRIPTION_LIMIT = 1024;
this.REFRESH_TOKEN_EXPIRES = 604800;
this.WX_SECRET = "";
this.WX_DEFAULT_ICON = 0;
this.WXCIRCLE_DEFAULT_ICON = 0;
this.isToCircle = false;
this.mRefreshTokenAvailable = true;
this.TAG = "UMWXHandler";
this.SHOW_COMPRESS_TOAST = 1;
this.SHOW_TITLE_TOAST = 2;
this.isShowCompressToast = true;
this.mReportDesc = "";
this.mWxMediaMessage = null;
this.isFromAuth = false;
this.isWXSceneFavorite = false;
this.handler = new Handler() {
public void handleMessage(Message msg) {
if(msg.what == 1 && UMWXHandler.this.isShowCompressToast) {
Toast.makeText(UMWXHandler.this.mContext, "图片大小超过32KB,正在对图片进行压缩...", 0).show();
} else if(msg.what == 2) {
Toast.makeText(UMWXHandler.this.mContext, "标题长度超过512 Bytes...", 0).show();
}
}
};
this.mEventHandler = new IWXAPIEventHandler() {
public void onResp(BaseResp resp) {
if(UMWXHandler.this.isFromAuth) {
UMWXHandler.this.dealOAuth(resp);
} else {
int statusCode = 0;
SHARE_MEDIA platform = SocializeConfig.getSelectedPlatfrom();
switch(resp.errCode) {
case -4:
statusCode = -4;
Log.d("UMWXHandler", "### 微信发送被拒绝");
break;
case -3:
statusCode = -3;
break;
case -2:
statusCode = '鱀';
Log.d("UMWXHandler", "### 微信分享取消");
break;
case -1:
statusCode = -1;
break;
case 0:
statusCode = 200;
Log.d("UMWXHandler", "### 微信分享成功.");
break;
default:
Log.d("UMWXHandler", "### 微信发送 -- 未知错误.");
}
if(!UMWXHandler.this.isFromAuth) {
UMWXHandler.this.mSocializeConfig.fireAllListenersOnComplete(SnsPostListener.class, platform, statusCode, UMWXHandler.mEntity);
if(statusCode == 200 && UMWXHandler.mEntity != null) {
SocializeUtils.sendAnalytic(UMWXHandler.this.mContext, UMWXHandler.mEntity.mDescriptor, UMWXHandler.this.mShareContent, UMWXHandler.this.mShareMedia, UMWXHandler.this.isToCircle?"wxtimeline":"wxsession");
}
}
}
}
public void onReq(BaseReq req) {
}
};
this.mContext = context.getApplicationContext();
this.WX_APPID = appid;
if(TextUtils.isEmpty(this.WX_APPID)) {
throw new NullPointerException("the weixin appid is null");
} else {
this.mWXApi = WXAPIFactory.createWXAPI(this.mContext, this.WX_APPID);
this.mWXApi.registerApp(this.WX_APPID);
this.WX_SECRET = secret;
this.mExtraData.put("wx_appid", this.WX_APPID);
if(TextUtils.isEmpty(this.WX_SECRET)) {
this.WX_SECRET = "";
}
this.mExtraData.put("wx_secret", this.WX_SECRET);
if(this.WX_DEFAULT_ICON == 0 || this.WXCIRCLE_DEFAULT_ICON == 0) {
this.WX_DEFAULT_ICON = ResContainer.getResourceId(context, ResType.DRAWABLE, "umeng_socialize_wechat");
this.WXCIRCLE_DEFAULT_ICON = ResContainer.getResourceId(context, ResType.DRAWABLE, "umeng_socialize_wxcircle");
}
}
}
然后,调用addToSocialSDK方法:
这是UMWXHandler的父类UMSsoHandler的一个方法,
public void addToSocialSDK() {
this.mSocializeConfig.addCustomPlatform(this.build());
this.mSocializeConfig.setSsoHandler(this);
}
然后分别调用addCustomPlatform方法和setSsoHandler方法:
public void addCustomPlatform(CustomPlatform var1) {
a((SnsPlatform)var1);
}
public void setSsoHandler(UMSsoHandler var1) {
if(var1 == null) {
Log.w(b, "ssoHander is null");
} else {
int var2 = var1.getRequstCode();
Log.d("", "#### set sso handler, code = " + var2);
f.put(var2, var1);
CustomPlatform var3 = var1.build();
if(var3 != null) {
this.addCustomPlatform(var3);
}
}
}
奶蛋的,友盟将代码混淆了,不过影响不大,a方法如下:
private static void a(SnsPlatform var0) {
if(var0 != null && !TextUtils.isEmpty(var0.mKeyword)) {
String var1 = var0.mKeyword;
if(t.containsKey(var1)) {
t.remove(var1);
}
t.put(var1, var0);
}
}
里面的t其实就是一个Map:
private static Map<String, SnsPlatform> t;
addCustomPlatform方法的参数为UMSsoHandler的build:
public final CustomPlatform build() {
return this.mCustomPlatform != null?this.mCustomPlatform:this.createNewPlatform();
}
调用了抽象方法createNewPlatform:
protected abstract CustomPlatform createNewPlatform();
于是我们去UMSsoHandler的子类UMWXHandler去看具体实现:
public final CustomPlatform createNewPlatform() {
int icon = this.isToCircle?this.WXCIRCLE_DEFAULT_ICON:this.WX_DEFAULT_ICON;
String keyWord = this.isToCircle?"weixin_circle":"weixin";
String showWord = this.isToCircle?"朋友圈":"微信";
this.mCustomPlatform = new CustomPlatform(keyWord, showWord, icon);
boolean grayIcon = false;
int grayIcon1;
if(this.isToCircle) {
grayIcon1 = ResContainer.getResourceId(this.mContext, ResType.DRAWABLE, "umeng_socialize_wxcircle_gray");
} else {
grayIcon1 = ResContainer.getResourceId(this.mContext, ResType.DRAWABLE, "umeng_socialize_wechat_gray");
}
this.mCustomPlatform.mGrayIcon = grayIcon1;
this.mCustomPlatform.mClickListener = new OnSnsPlatformClickListener() {
public void onClick(Context context, SocializeEntity entity, SnsPostListener listener) {
UMWXHandler.this.handleOnClick(context, UMWXHandler.this.mCustomPlatform, entity, listener);
}
};
return this.mCustomPlatform;
}
感觉addCustomPlatform方法和setSsoHandler方法最后都是调用build,并添加到map啊,不知道为什么要弄成两个方法。
3.第二步:设置分享内容
//设置微信好友分享内容
WeiXinShareContent wx = new WeiXinShareContent();
wx.setShareContent("车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
wx.setTitle("买好车,上车城!");
wx.setTargetUrl("http://www.che.com");
wx.setShareMedia(urlImage);
mController.setShareMedia(wx);
WeiXinShareContent是继承自BaseShareContent的一个实体类,BaseShareContent又继承自SimpleShareContent,SimpleShareContent实现了UMediaObject接口,UMediaObject接口继承了Parcelable, Cloneable这两个接口。
这段代码用到了一个UMSocialService对象mController,它是我的主持类的静态变量
// 整个平台的Controller, 负责管理整个SDK的配置、操作等处理
public static UMSocialService mController = UMServiceFactory.getUMSocialService("test");
看getUMSocialService方法:
public static UMSocialService getUMSocialService(String var0) {
return getUMSocialService(var0, (RequestType)null);
}
转到两个参数的去:
@Deprecated
public static UMSocialService getUMSocialService(String var0, RequestType var1) {
SocializeEntity var2 = null;
if(var1 == null) {
var1 = RequestType.SOCIAL;
}
String var3 = var0 + var1;
if(c.g.containsKey(var3)) {
var2 = (SocializeEntity)c.g.get(var3);
return new c(var2);
} else {
var3 = var0 + RequestType.SOCIAL;
if(var1 == RequestType.ANALYTICS && c.g.containsKey(var3)) {
SocializeEntity var4 = (SocializeEntity)c.g.get(var3);
var2 = SocializeEntity.cloneNew(var4, var1);
} else {
var2 = new SocializeEntity(var0, var1);
}
return new c(var2);
}
}
转到c.g.get方法,c类继承自InitializeController并实现了UMSocialService,g是一个Map,
public static volatile Map<String, SocializeEntity> g = new HashMap();
最后返回时,调用了c的构造器:
public c(SocializeEntity var1) {
super(var1);
}
跳到父类InitializeController:
public InitializeController(SocializeEntity var1) {
super(var1);
}
跳到父类BaseController:
public BaseController(SocializeEntity var1) {
this.a = var1;
this.c = (CommentService)b.a(this.a, a.b, new Object[0]);
this.d = (LikeService)b.a(this.a, a.d, new Object[0]);
this.e = (AuthService)b.a(this.a, a.a, new Object[0]);
this.b = (ShareService)b.a(this.a, a.c, new Object[0]);
this.f = (UserCenterService)b.a(this.a, a.e, new Object[]{this.e});
}
奶蛋的,又尼玛混淆了,不要不要紧。反正都是初始化变量,没调用什么方法,可以略过。UMSocialService对象的初始化就到这里了,下面要调用setShareMedia方法:
boolean setShareMedia(UMediaObject var1);
这是UMSocialService接口的一个方法,那么它的实现应该就是在c类中了,去找:
public boolean setShareMedia(UMediaObject var1) {
if(var1 == null) {
this.a.setMedia((UMediaObject)null);
return true;
} else if(var1.isMultiMedia()) {
this.a.setMedia(var1);
return true;
} else {
Log.w(h, "unable set share media.type is no support.");
return false;
}
}
调用一个SocializeEntity对象a的setMedia方法:
public void setMedia(UMediaObject var1) {
SHARE_MEDIA var2 = SHARE_MEDIA.GENERIC;
if(var1 != null) {
var2 = var1.getTargetPlatform();
}
if(this.h.containsKey(var2)) {
this.h.remove(var2);
}
this.h.put(var2, var1);
}
用SocializeEntity类的一个Map存储:
private Map<SHARE_MEDIA, UMediaObject> h = new HashMap();
这里的SHARE_MEDIA是一个枚举类。我们看它的类型WEIXIN:
WEIXIN("weixin") {
public int getReqCode() {
return 10086;
}
public boolean isSupportAuthorization() {
return true;
}
},
4.第三步:弹出分享对话框
mController.getConfig().setPlatforms(SHARE_MEDIA.WEIXIN,SHARE_MEDIA.WEIXIN_CIRCLE,SHARE_MEDIA.SINA);
mController.openShare(activity, false);
看设置需要显示的分享平台的方法:
public void setPlatforms(SHARE_MEDIA... var1) {
this.v.clear();
if(var1 != null && var1.length > 0) {
SHARE_MEDIA[] var2 = var1;
int var3 = var1.length;
for(int var4 = 0; var4 < var3; ++var4) {
SHARE_MEDIA var5 = var2[var4];
if(SocializeUtils.isValidPlatform(var5)) {
this.v.add(var5);
}
}
}
}
用SocializeConfig类中的一个List存储:
private List<SHARE_MEDIA> v;
再来看openShare方法,这是ShareService的一个方法:
void openShare(Activity var1, boolean var2);
实现在哪里呢?UMSocialService中找不到。谁是UMSocialService的实现类?就是之前的那个c类。
public void openShare(Activity var1, boolean var2) {
this.b.openShare(var1, var2);
}
再去看b类:
public void openShare(Activity var1, boolean var2) {
this.g = var2;
this.openShare(var1, (SnsPostListener)null);
}
转到:
public void openShare(Activity var1, SnsPostListener var2) {
this.a();
if(this.e(var1)) {
this.a(var1);
this.a.addStatisticsData(var1, SHARE_MEDIA.GENERIC, 1);
this.f = null;
a var3 = new a(var1);
var3.setLayoutParams(new LayoutParams(-1, -1));
this.f = new com.umeng.socialize.view.b(var1, var3, UMServiceFactory.getUMSocialService(this.a.mDescriptor));
this.f.setFocusable(true);
this.f.setBackgroundDrawable(new BitmapDrawable());
this.f.a(this.i);
var3.a(new OnClickListener() {
public void onClick(View var1) {
b.this.f.dismiss();
}
});
if(var2 != null) {
this.c.registerListener(var2);
}
if(this.g) {
this.d(var1);
} else {
this.f.showAtLocation(var1.getWindow().getDecorView(), 80, 0, 0);
}
}
}
转到PopupWindow类的子类b:
public void showAtLocation(View var1, int var2, int var3, int var4) {
try {
super.showAtLocation(var1, var2, var3, var4);
if(this.e != null) {
this.e.onShow();
}
} catch (Exception var6) {
var6.printStackTrace();
}
}
这个PopupWindow的视图是根据SocializeConfig类中的那个List来创建的:
创建的视图的点击事件:
var4.setOnClickListener(new OnClickListener() {
public void onClick(View var1x) {
b.this.dismiss();
SHARE_MEDIA var2 = SHARE_MEDIA.convertToEmun(var3.mKeyword);
if(!DeviceConfig.isNetworkAvailable(b.this.a) && var2 != SHARE_MEDIA.SMS) {
Toast.makeText(b.this.a, "您的网络不可用,请检查网络连接...", 0).show();
} else {
a(var3, var2);
}
}
});
跳转到a:
private void a(SnsPlatform var1x, SHARE_MEDIA var2) {
if(var2 != null) {
b.this.c.getEntity().addStatisticsData(b.this.a, var2, 14);
}
if(var1x != null) {
SocializeConfig.setSelectedPlatfrom(var2);
SnsPostListener var3 = ListenerUtils.createSnsPostListener();
var1x.performClick(b.this.a, b.this.c.getEntity(), var3);
}
}
点击了之后如何执行的呢?
转到SnsPlatform类的performClick方法
public void performClick(Context var1, SocializeEntity var2, SnsPostListener var3) {
if(this.mClickListener != null) {
this.mClickListener.onClick(var1, var2, var3);
}
}
转到OnSnsPlatformClickListener:
public interface OnSnsPlatformClickListener {
void onClick(Context var1, SocializeEntity var2, SocializeListeners.SnsPostListener var3);
}
但是,SnsPlatform类的OnSnsPlatformClickListener并没有初始化,于是去它的子类,那么,谁是SnsPlatform的实现类?
未完待续……