69.源码解析:友盟分享

1.分享的主持类

  1. public class SharePresenter {
  2. //QQ分享帐号
  3. private final static String QQ_AppID = "***";
  4. private final static String QQ_AppKey = "***";
  5. //微信分享帐号
  6. private final static String WX_AppID = "***";
  7. private final static String WX_AppKey = "***";
  8. // 整个平台的Controller, 负责管理整个SDK的配置、操作等处理
  9. public static UMSocialService mController = UMServiceFactory.getUMSocialService("test");
  10. private static void init(Activity activity) {
  11. initPlatforms(activity);
  12. initShareContent(activity);
  13. }
  14. /**
  15. * 配置平台
  16. */
  17. private static void initPlatforms(Activity activity) {
  18. // 添加新浪SSO授权
  19. mController.getConfig().setSsoHandler(new SinaSsoHandler());
  20. // 添加QQ支持, 并且设置QQ分享内容的target url
  21. UMQQSsoHandler qqSsoHandler = new UMQQSsoHandler(activity,QQ_AppID,QQ_AppKey);
  22. qqSsoHandler.addToSocialSDK();
  23. // 添加QZone平台
  24. QZoneSsoHandler qZoneSsoHandler = new QZoneSsoHandler(activity,QQ_AppID,QQ_AppKey);
  25. qZoneSsoHandler.addToSocialSDK();
  26. // 添加微信平台
  27. UMWXHandler wxHandler = new UMWXHandler(activity, WX_AppID, WX_AppKey);
  28. wxHandler.addToSocialSDK();
  29. // 支持微信朋友圈
  30. UMWXHandler wxCircleHandler = new UMWXHandler(activity, WX_AppID, WX_AppKey);
  31. wxCircleHandler.setToCircle(true);
  32. wxCircleHandler.addToSocialSDK();
  33. }
  34. /**
  35. * 配置分享内容
  36. */
  37. private static void initShareContent(Activity activity) {
  38. UMImage urlImage = new UMImage(activity,"http://www.che.com/upload/system/d95aa9d7-7980-4f61-84e1-3c28d320d051.png");
  39. // 设置QQ空间分享内容
  40. QZoneShareContent qzone = new QZoneShareContent();
  41. qzone.setTitle("车城网分享测试");
  42. qzone.setShareContent("买好车,上车城!");
  43. qzone.setTargetUrl("http://www.che.com");
  44. mController.setShareMedia(qzone);
  45. // 设置QQ好友分享内容
  46. QQShareContent qq = new QQShareContent();
  47. qq.setTitle("车城网分享测试");
  48. qq.setShareContent("买好车,上车城!");
  49. qq.setTargetUrl("http://www.che.com");
  50. mController.setShareMedia(qq);
  51. //设置新浪微博分享内容
  52. SinaShareContent sina = new SinaShareContent();
  53. sina.setShareContent("买好车,上车城!车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
  54. sina.setShareImage(new UMImage(activity, R.drawable.ic_main));
  55. mController.setShareMedia(sina);
  56. //设置微信好友分享内容
  57. WeiXinShareContent wx = new WeiXinShareContent();
  58. wx.setShareContent("车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
  59. wx.setTitle("买好车,上车城!");
  60. wx.setTargetUrl("http://www.che.com");
  61. wx.setShareMedia(urlImage);
  62. mController.setShareMedia(wx);
  63. // 设置朋友圈分享的内容
  64. CircleShareContent circle = new CircleShareContent();
  65. circle.setShareContent("车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
  66. circle.setTitle("买好车,上车城!");
  67. circle.setTargetUrl("http://www.che.com");
  68. circle.setShareMedia(urlImage);
  69. mController.setShareMedia(circle);
  70. }
  71. /**
  72. * 弹出对话框,分享到微信、QQ、新浪等
  73. */
  74. public static void share(Activity activity) {
  75. init(activity);
  76. mController.getConfig().setPlatforms(SHARE_MEDIA.WEIXIN,SHARE_MEDIA.WEIXIN_CIRCLE,SHARE_MEDIA.SINA);
  77. mController.openShare(activity, false);
  78. }
  79. /**
  80. * 弹出对话框,分享到微信、QQ、新浪等
  81. */
  82. public static void share(Activity activity,String shareCarName,String sharePrice,String shareImageUrl,String shareUrl) {
  83. LogUtil.e("shareCarName"+shareCarName+"\tshareImageUrl="+shareImageUrl+"\tshareUrl="+shareUrl);
  84. initPlatforms(activity);
  85. initShareContent(activity, shareCarName, sharePrice, shareImageUrl, shareUrl);
  86. mController.getConfig().setPlatforms(SHARE_MEDIA.WEIXIN,SHARE_MEDIA.WEIXIN_CIRCLE,SHARE_MEDIA.SINA);
  87. mController.openShare(activity, false);
  88. }
  89. /**
  90. * 配置分享内容
  91. */
  92. private static void initShareContent(Activity activity,String shareCarName,String sharePrice,String shareImageUrl,String shareUrl) {
  93. shareImageUrl="http://www.che.com/upload/system/d95aa9d7-7980-4f61-84e1-3c28d320d051.png";
  94. UMImage urlImage = new UMImage(activity,shareImageUrl);
  95. //设置新浪微博分享内容
  96. SinaShareContent sina = new SinaShareContent();
  97. sina.setShareContent("买好车,上车城!车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
  98. sina.setShareImage(new UMImage(activity, R.drawable.isloading));
  99. mController.setShareMedia(sina);
  100. //设置微信好友分享内容
  101. WeiXinShareContent wx = new WeiXinShareContent();
  102. wx.setShareContent("车城交易价: "+sharePrice+",来车城分期贷款:支持0首付,车险办理,代办过户、延保");
  103. wx.setTitle(shareCarName);
  104. wx.setTargetUrl(shareUrl);
  105. wx.setShareMedia(urlImage);
  106. mController.setShareMedia(wx);
  107. // 设置朋友圈分享的内容
  108. CircleShareContent circle = new CircleShareContent();
  109. circle.setShareContent("车城交易价: "+sharePrice+",来车城分期贷款:支持0首付,车险办理,代办过户、延保");
  110. circle.setTitle(shareCarName);
  111. circle.setTargetUrl(shareUrl);
  112. circle.setShareMedia(urlImage);
  113. mController.setShareMedia(circle);
  114. }
  115. }

2.第一步:配置平台

  1. // 添加微信平台
  2. UMWXHandler wxHandler = new UMWXHandler(activity, WX_AppID, WX_AppKey);
  3. wxHandler.addToSocialSDK();
首先,创建UMWXHandler:
  1. public UMWXHandler(Context context, String appid, String secret) {
  2. this.THUMB_SIZE = 150;
  3. this.THUMB_LIMIT = '耀';
  4. this.TITLE_LIMIT = 512;
  5. this.DESCRIPTION_LIMIT = 1024;
  6. this.REFRESH_TOKEN_EXPIRES = 604800;
  7. this.WX_SECRET = "";
  8. this.WX_DEFAULT_ICON = 0;
  9. this.WXCIRCLE_DEFAULT_ICON = 0;
  10. this.isToCircle = false;
  11. this.mRefreshTokenAvailable = true;
  12. this.TAG = "UMWXHandler";
  13. this.SHOW_COMPRESS_TOAST = 1;
  14. this.SHOW_TITLE_TOAST = 2;
  15. this.isShowCompressToast = true;
  16. this.mReportDesc = "";
  17. this.mWxMediaMessage = null;
  18. this.isFromAuth = false;
  19. this.isWXSceneFavorite = false;
  20. this.handler = new Handler() {
  21. public void handleMessage(Message msg) {
  22. if(msg.what == 1 && UMWXHandler.this.isShowCompressToast) {
  23. Toast.makeText(UMWXHandler.this.mContext, "图片大小超过32KB,正在对图片进行压缩...", 0).show();
  24. } else if(msg.what == 2) {
  25. Toast.makeText(UMWXHandler.this.mContext, "标题长度超过512 Bytes...", 0).show();
  26. }
  27. }
  28. };
  29. this.mEventHandler = new IWXAPIEventHandler() {
  30. public void onResp(BaseResp resp) {
  31. if(UMWXHandler.this.isFromAuth) {
  32. UMWXHandler.this.dealOAuth(resp);
  33. } else {
  34. int statusCode = 0;
  35. SHARE_MEDIA platform = SocializeConfig.getSelectedPlatfrom();
  36. switch(resp.errCode) {
  37. case -4:
  38. statusCode = -4;
  39. Log.d("UMWXHandler", "### 微信发送被拒绝");
  40. break;
  41. case -3:
  42. statusCode = -3;
  43. break;
  44. case -2:
  45. statusCode = '鱀';
  46. Log.d("UMWXHandler", "### 微信分享取消");
  47. break;
  48. case -1:
  49. statusCode = -1;
  50. break;
  51. case 0:
  52. statusCode = 200;
  53. Log.d("UMWXHandler", "### 微信分享成功.");
  54. break;
  55. default:
  56. Log.d("UMWXHandler", "### 微信发送 -- 未知错误.");
  57. }
  58. if(!UMWXHandler.this.isFromAuth) {
  59. UMWXHandler.this.mSocializeConfig.fireAllListenersOnComplete(SnsPostListener.class, platform, statusCode, UMWXHandler.mEntity);
  60. if(statusCode == 200 && UMWXHandler.mEntity != null) {
  61. SocializeUtils.sendAnalytic(UMWXHandler.this.mContext, UMWXHandler.mEntity.mDescriptor, UMWXHandler.this.mShareContent, UMWXHandler.this.mShareMedia, UMWXHandler.this.isToCircle?"wxtimeline":"wxsession");
  62. }
  63. }
  64. }
  65. }
  66. public void onReq(BaseReq req) {
  67. }
  68. };
  69. this.mContext = context.getApplicationContext();
  70. this.WX_APPID = appid;
  71. if(TextUtils.isEmpty(this.WX_APPID)) {
  72. throw new NullPointerException("the weixin appid is null");
  73. } else {
  74. this.mWXApi = WXAPIFactory.createWXAPI(this.mContext, this.WX_APPID);
  75. this.mWXApi.registerApp(this.WX_APPID);
  76. this.WX_SECRET = secret;
  77. this.mExtraData.put("wx_appid", this.WX_APPID);
  78. if(TextUtils.isEmpty(this.WX_SECRET)) {
  79. this.WX_SECRET = "";
  80. }
  81. this.mExtraData.put("wx_secret", this.WX_SECRET);
  82. if(this.WX_DEFAULT_ICON == 0 || this.WXCIRCLE_DEFAULT_ICON == 0) {
  83. this.WX_DEFAULT_ICON = ResContainer.getResourceId(context, ResType.DRAWABLE, "umeng_socialize_wechat");
  84. this.WXCIRCLE_DEFAULT_ICON = ResContainer.getResourceId(context, ResType.DRAWABLE, "umeng_socialize_wxcircle");
  85. }
  86. }
  87. }
然后,调用addToSocialSDK方法
这是UMWXHandler的父类UMSsoHandler的一个方法,
  1. public void addToSocialSDK() {
  2. this.mSocializeConfig.addCustomPlatform(this.build());
  3. this.mSocializeConfig.setSsoHandler(this);
  4. }
然后分别调用addCustomPlatform方法和setSsoHandler方法:
  1. public void addCustomPlatform(CustomPlatform var1) {
  2. a((SnsPlatform)var1);
  3. }
  1. public void setSsoHandler(UMSsoHandler var1) {
  2. if(var1 == null) {
  3. Log.w(b, "ssoHander is null");
  4. } else {
  5. int var2 = var1.getRequstCode();
  6. Log.d("", "#### set sso handler, code = " + var2);
  7. f.put(var2, var1);
  8. CustomPlatform var3 = var1.build();
  9. if(var3 != null) {
  10. this.addCustomPlatform(var3);
  11. }
  12. }
  13. }
奶蛋的,友盟将代码混淆了,不过影响不大,a方法如下:
  1. private static void a(SnsPlatform var0) {
  2. if(var0 != null && !TextUtils.isEmpty(var0.mKeyword)) {
  3. String var1 = var0.mKeyword;
  4. if(t.containsKey(var1)) {
  5. t.remove(var1);
  6. }
  7. t.put(var1, var0);
  8. }
  9. }
里面的t其实就是一个Map:
  1. private static Map<String, SnsPlatform> t;
addCustomPlatform方法的参数为UMSsoHandler的build:
  1. public final CustomPlatform build() {
  2. return this.mCustomPlatform != null?this.mCustomPlatform:this.createNewPlatform();
  3. }
调用了抽象方法createNewPlatform:
  1. protected abstract CustomPlatform createNewPlatform();
于是我们去UMSsoHandler的子类UMWXHandler去看具体实现:
  1. public final CustomPlatform createNewPlatform() {
  2. int icon = this.isToCircle?this.WXCIRCLE_DEFAULT_ICON:this.WX_DEFAULT_ICON;
  3. String keyWord = this.isToCircle?"weixin_circle":"weixin";
  4. String showWord = this.isToCircle?"朋友圈":"微信";
  5. this.mCustomPlatform = new CustomPlatform(keyWord, showWord, icon);
  6. boolean grayIcon = false;
  7. int grayIcon1;
  8. if(this.isToCircle) {
  9. grayIcon1 = ResContainer.getResourceId(this.mContext, ResType.DRAWABLE, "umeng_socialize_wxcircle_gray");
  10. } else {
  11. grayIcon1 = ResContainer.getResourceId(this.mContext, ResType.DRAWABLE, "umeng_socialize_wechat_gray");
  12. }
  13. this.mCustomPlatform.mGrayIcon = grayIcon1;
  14. this.mCustomPlatform.mClickListener = new OnSnsPlatformClickListener() {
  15. public void onClick(Context context, SocializeEntity entity, SnsPostListener listener) {
  16. UMWXHandler.this.handleOnClick(context, UMWXHandler.this.mCustomPlatform, entity, listener);
  17. }
  18. };
  19. return this.mCustomPlatform;
  20. }
感觉addCustomPlatform方法和setSsoHandler方法最后都是调用build,并添加到map啊,不知道为什么要弄成两个方法。

3.第二步:设置分享内容

  1. //设置微信好友分享内容
  2. WeiXinShareContent wx = new WeiXinShareContent();
  3. wx.setShareContent("车城是结合线上网络展示、线下展厅销售、金融服务的综合服务平台。http://www.che.com");
  4. wx.setTitle("买好车,上车城!");
  5. wx.setTargetUrl("http://www.che.com");
  6. wx.setShareMedia(urlImage);
  7. mController.setShareMedia(wx);
WeiXinShareContent是继承自BaseShareContent的一个实体类,BaseShareContent又继承自SimpleShareContent,SimpleShareContent实现了UMediaObject接口,UMediaObject接口继承了Parcelable, Cloneable这两个接口。

这段代码用到了一个UMSocialService对象mController,它是我的主持类的静态变量
  1. // 整个平台的Controller, 负责管理整个SDK的配置、操作等处理
  2. public static UMSocialService mController = UMServiceFactory.getUMSocialService("test");
看getUMSocialService方法:
  1. public static UMSocialService getUMSocialService(String var0) {
  2. return getUMSocialService(var0, (RequestType)null);
  3. }
转到两个参数的去:
  1. @Deprecated
  2. public static UMSocialService getUMSocialService(String var0, RequestType var1) {
  3. SocializeEntity var2 = null;
  4. if(var1 == null) {
  5. var1 = RequestType.SOCIAL;
  6. }
  7. String var3 = var0 + var1;
  8. if(c.g.containsKey(var3)) {
  9. var2 = (SocializeEntity)c.g.get(var3);
  10. return new c(var2);
  11. } else {
  12. var3 = var0 + RequestType.SOCIAL;
  13. if(var1 == RequestType.ANALYTICS && c.g.containsKey(var3)) {
  14. SocializeEntity var4 = (SocializeEntity)c.g.get(var3);
  15. var2 = SocializeEntity.cloneNew(var4, var1);
  16. } else {
  17. var2 = new SocializeEntity(var0, var1);
  18. }
  19. return new c(var2);
  20. }
  21. }
转到c.g.get方法,c类继承自InitializeController并实现了UMSocialService,g是一个Map,
  1. public static volatile Map<String, SocializeEntity> g = new HashMap();
最后返回时,调用了c的构造器:
  1. public c(SocializeEntity var1) {
  2. super(var1);
  3. }
跳到父类InitializeController:
  1. public InitializeController(SocializeEntity var1) {
  2. super(var1);
  3. }
跳到父类BaseController:
  1. public BaseController(SocializeEntity var1) {
  2. this.a = var1;
  3. this.c = (CommentService)b.a(this.a, a.b, new Object[0]);
  4. this.d = (LikeService)b.a(this.a, a.d, new Object[0]);
  5. this.e = (AuthService)b.a(this.a, a.a, new Object[0]);
  6. this.b = (ShareService)b.a(this.a, a.c, new Object[0]);
  7. this.f = (UserCenterService)b.a(this.a, a.e, new Object[]{this.e});
  8. }
奶蛋的,又尼玛混淆了,不要不要紧。反正都是初始化变量,没调用什么方法,可以略过。UMSocialService对象的初始化就到这里了,下面要调用setShareMedia方法:
  1. boolean setShareMedia(UMediaObject var1);
这是UMSocialService接口的一个方法,那么它的实现应该就是在c类中了,去找:
  1. public boolean setShareMedia(UMediaObject var1) {
  2. if(var1 == null) {
  3. this.a.setMedia((UMediaObject)null);
  4. return true;
  5. } else if(var1.isMultiMedia()) {
  6. this.a.setMedia(var1);
  7. return true;
  8. } else {
  9. Log.w(h, "unable set share media.type is no support.");
  10. return false;
  11. }
  12. }
调用一个SocializeEntity对象a的setMedia方法:
  1. public void setMedia(UMediaObject var1) {
  2. SHARE_MEDIA var2 = SHARE_MEDIA.GENERIC;
  3. if(var1 != null) {
  4. var2 = var1.getTargetPlatform();
  5. }
  6. if(this.h.containsKey(var2)) {
  7. this.h.remove(var2);
  8. }
  9. this.h.put(var2, var1);
  10. }
SocializeEntity类的一个Map存储:
  1. private Map<SHARE_MEDIA, UMediaObject> h = new HashMap();
这里的SHARE_MEDIA是一个枚举类。我们看它的类型WEIXIN:
  1. WEIXIN("weixin") {
  2. public int getReqCode() {
  3. return 10086;
  4. }
  5. public boolean isSupportAuthorization() {
  6. return true;
  7. }
  8. },

4.第三步:弹出分享对话框

  1. mController.getConfig().setPlatforms(SHARE_MEDIA.WEIXIN,SHARE_MEDIA.WEIXIN_CIRCLE,SHARE_MEDIA.SINA);
  2. mController.openShare(activity, false);
看设置需要显示的分享平台的方法:
  1. public void setPlatforms(SHARE_MEDIA... var1) {
  2. this.v.clear();
  3. if(var1 != null && var1.length > 0) {
  4. SHARE_MEDIA[] var2 = var1;
  5. int var3 = var1.length;
  6. for(int var4 = 0; var4 < var3; ++var4) {
  7. SHARE_MEDIA var5 = var2[var4];
  8. if(SocializeUtils.isValidPlatform(var5)) {
  9. this.v.add(var5);
  10. }
  11. }
  12. }
  13. }
SocializeConfig类中的一个List存储:
  1. private List<SHARE_MEDIA> v;
再来看openShare方法,这是ShareService的一个方法:
  1. void openShare(Activity var1, boolean var2);
实现在哪里呢?UMSocialService中找不到。谁是UMSocialService的实现类?就是之前的那个c类。
  1. public void openShare(Activity var1, boolean var2) {
  2. this.b.openShare(var1, var2);
  3. }
再去看b类
  1. public void openShare(Activity var1, boolean var2) {
  2. this.g = var2;
  3. this.openShare(var1, (SnsPostListener)null);
  4. }
转到:
  1. public void openShare(Activity var1, SnsPostListener var2) {
  2. this.a();
  3. if(this.e(var1)) {
  4. this.a(var1);
  5. this.a.addStatisticsData(var1, SHARE_MEDIA.GENERIC, 1);
  6. this.f = null;
  7. a var3 = new a(var1);
  8. var3.setLayoutParams(new LayoutParams(-1, -1));
  9. this.f = new com.umeng.socialize.view.b(var1, var3, UMServiceFactory.getUMSocialService(this.a.mDescriptor));
  10. this.f.setFocusable(true);
  11. this.f.setBackgroundDrawable(new BitmapDrawable());
  12. this.f.a(this.i);
  13. var3.a(new OnClickListener() {
  14. public void onClick(View var1) {
  15. b.this.f.dismiss();
  16. }
  17. });
  18. if(var2 != null) {
  19. this.c.registerListener(var2);
  20. }
  21. if(this.g) {
  22. this.d(var1);
  23. } else {
  24. this.f.showAtLocation(var1.getWindow().getDecorView(), 80, 0, 0);
  25. }
  26. }
  27. }
转到PopupWindow类的子类b:
  1. public void showAtLocation(View var1, int var2, int var3, int var4) {
  2. try {
  3. super.showAtLocation(var1, var2, var3, var4);
  4. if(this.e != null) {
  5. this.e.onShow();
  6. }
  7. } catch (Exception var6) {
  8. var6.printStackTrace();
  9. }
  10. }
这个PopupWindow的视图是根据SocializeConfig类中的那个List来创建的:
创建的视图的点击事件:
  1. var4.setOnClickListener(new OnClickListener() {
  2. public void onClick(View var1x) {
  3. b.this.dismiss();
  4. SHARE_MEDIA var2 = SHARE_MEDIA.convertToEmun(var3.mKeyword);
  5. if(!DeviceConfig.isNetworkAvailable(b.this.a) && var2 != SHARE_MEDIA.SMS) {
  6. Toast.makeText(b.this.a, "您的网络不可用,请检查网络连接...", 0).show();
  7. } else {
  8. a(var3, var2);
  9. }
  10. }
  11. });
跳转到a:
  1. private void a(SnsPlatform var1x, SHARE_MEDIA var2) {
  2. if(var2 != null) {
  3. b.this.c.getEntity().addStatisticsData(b.this.a, var2, 14);
  4. }
  5. if(var1x != null) {
  6. SocializeConfig.setSelectedPlatfrom(var2);
  7. SnsPostListener var3 = ListenerUtils.createSnsPostListener();
  8. var1x.performClick(b.this.a, b.this.c.getEntity(), var3);
  9. }
  10. }
点击了之后如何执行的呢?
转到SnsPlatform类的performClick方法
  1. public void performClick(Context var1, SocializeEntity var2, SnsPostListener var3) {
  2. if(this.mClickListener != null) {
  3. this.mClickListener.onClick(var1, var2, var3);
  4. }
  5. }
转到OnSnsPlatformClickListener:
  1. public interface OnSnsPlatformClickListener {
  2. void onClick(Context var1, SocializeEntity var2, SocializeListeners.SnsPostListener var3);
  3. }
但是,SnsPlatform类的OnSnsPlatformClickListener并没有初始化,于是去它的子类,那么,谁是SnsPlatform的实现类?

未完待续……











posted @ 2015-12-25 19:18  yutianran  阅读(1174)  评论(0编辑  收藏  举报