zoukankan      html  css  js  c++  java
  • 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+" shareImageUrl="+shareImageUrl+" shareUrl="+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的实现类?

    未完待续……











  • 相关阅读:
    JVM classloader
    面试整理
    工具配置链接
    IntelliJ IDEA 热部署
    IntelliJ IDEA 常用快捷键
    类文件结构
    判断对象存活的方法
    JVM 运行时数据区域
    vim编辑16进制
    阿里云yum源
  • 原文地址:https://www.cnblogs.com/yutianran/p/5076769.html
Copyright © 2011-2022 走看看