热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

记录Android微信分享功能的吐槽与思考

Android记录一次开发微信分享功能的吐槽与思考,感兴趣的小伙伴们可以参考一下

在App内潜入分享到微信好友或朋友圈的功能想必大家已经屡见不鲜了,比如Android分享一个网页信息(URL)到微信客户端的代码:

 /**
 * 微信分享:分享网页
 * @param context
 * @param url
 * @param title
 * @param description
 * @param scene
 */
 public static void shareToWeChatWithWebpage(Context context, String url,
 String title, String description, int scene){
 IWXAPI iwxapi = WXAPIFactory.createWXAPI(context, WXEntryActivity.WXAPI_APP_ID);
 if (!iwxapi.isWXAppInstalled()){
 ToastManager.getInstance(context.getApplicationContext()).showToast("您尚未安装微信客户端");
 return;
 }
 WXWebpageObject wxWebpageObject = new WXWebpageObject();
 wxWebpageObject.webpageUrl = url;
 WXMediaMessage wxMediaMessage = new WXMediaMessage(wxWebpageObject);
 wxMediaMessage.mediaObject = wxWebpageObject;
 wxMediaMessage.title = title;
 wxMediaMessage.description = description;
 wxMediaMessage.thumbData =
 ImageManager.bmpToByteArray(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_share_invite), true);
 SendMessageToWX.Req req = new SendMessageToWX.Req();
 req.transaction = String.valueOf(System.currentTimeMillis());
 req.message = wxMediaMessage;
 req.scene = scene;
 iwxapi.sendReq(req);
 } 

虽然已经在不同的App内使用了N遍,但在最近的一个项目中还是出了错:执行完这段代码,应用没有任何反应,无法调起微信客户端,并且没有任何错误信息打印提示。不得已查看官方资料 —— [Android常见问题],找到这样一段提示: 

Q:调用wxapi.sendReq接口,返回true,但微信客户端并未启动,请检查以下几项:
A:
 1)微信是否安装
 2)调用时的Apk包名和签名是否与开放平台填写的一致,签名请使用该工具:点击下载,常发生在安装了debug版本又安装release版本情况,确定包名签名后卸载微信重装或者清除微信数据再做测试
 3)检查发送时的缩略图大小是否超过32k
 4)能够调起微信到选择好友列表,但是点击发送后无响应,请检查proguard配置是否对微信SDK代码进行了混淆,建议不要对SDK对混淆,参考以下proguard配置:
 -keep class com.tencent.mm.sdk.** {
 *;

经检查,发现代码iwxapi.sendReq(req);执行过后返回了false,其实按照上面Q&A的写法,已经不属于该问题范畴了。但是还是照着这四点检查了一遍,发送的缩略图本地预览大小只有不到20KB,其他配置也没有问题,可还是出错,到底问题出在哪里了呢?
 纠结,沉思,差点就怀疑人生了!最后冒着试一试的态度,我把缩略图换成一张不到7KB的小图,再次执行代码,结果惊人地发现:iwxapi.sendReq(req);返回true,并成功调起微信客户端!当时心中一万头草泥马奔腾而过啊!
 一番激动之后,就开始研究了,为什么之前使用的缩略图没有超过官网文档32K的限制,却无法调起微信客户端呢,难道官网文档写错了,上限不是32KB?于是回归源码,打开微信SDK提供的类WXMediaMessage,找到如下定义的一系列常量:

public static final int THUMB_LENGTH_LIMIT = 32768;
private static final int TITLE_LENGTH_LIMIT = 512;
private static final int DESCRIPTION_LENGTH_LIMIT = 1024;
private static final int MEDIA_TAG_NAME_LENGTH_LIMIT = 64;
private static final int MESSAGE_ACTION_LENGTH_LIMIT = 2048;
private static final int MESSAGE_EXT_LENGTH_LIMIT = 2048; 

果不其然,微信SDK对于分享到微信的缩略图大小、标题长度、描述长度等信息都做了限制。其中,缩略图大小限制为32768,源码中并没有注释写明单位。好奇的我将其除以1024,刚好得到32,这不就是官网文档提到的上限值32KB嘛(说明源码中的数值单位为Byte)!那就是说官网文档没有写错,可是问题出在哪儿了呢?
 其实事关图片的实际硬盘占用大小和内存占用大小问题。存放在电脑硬盘中的图片文件,会根据不同图片格式的压缩规则进行压缩,从而减少硬盘占用大小,比如常见如JPEG这种有损压缩的图片格式。而在Android系统中,将图像读取到内存当中所占用的内存大小与图片存放在硬盘当中的实际大小没有一点关系,可能更大,也可能更小,使用如下代码即可获取图像所占用的内存大小:

 private Bitmap decodeResource(Resources resources, int id) {
TypedValue value = new TypedValue();
resources.openRawResource(id, value);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inTargetDensity = value.density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, id, opts);
Log.i("Bitmap", "size is " + bitmap.getRowBytes() * bitmap.getHeight());
return bitmap;
} 

其中,bitmap.getRowBytes() * bitmap.getHeight()获取的便是Bitmap的内存占用大小,单位为Byte,再除以1024,便可以转换为BK单位。注意:上述从资源中获取Bitmap对象的过程,并没有直接使用decodeResource(Resources res, int id)含带两个参数的方法,是为了避免由于图片存放在不同drawable或者mipmap文件夹下导致的内存占用不一致问题,对Android屏幕适配有所了解的朋友应该懂得这个,这里就不细说了,大家可以参考凯子哥的一篇文章 —— [关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析]。
 通过PS工具,修改缩略图尺寸大小,然后通过上面这段代码测试不同大小的图片在Android手机中所占用的内存大小,同时查看是否可以调起微信客户端。经过这样的测试,最终发现,微信SDK和官方文档中的32KB缩略图上限大小指的是内存占用大小,而非图片的硬盘占用大小。这样,也就解决了前面我所遇到的问题。
 最后,还是得吐槽一下Android微信SDK的诟病,也是一些包括支付宝SDK在内其他第三方服务供应商的通用问题,别无他意,仅作发泄:
 •签名唯一性
 做Android开发的都知道,开发过程中编译打包并运行在手机或模拟器上的apk文件使用的是IDE提供的默认通用签名,而正式上线发布的apk文件使用的是开发人员自定义的正式签名文件。微信SDK在注册应用时只能输入一个签名信息,导致必须在正式包中测试微信SDK相关功能,而正式包又无法做到跟踪调试,非常不方便。当然你也可以这样做,处于开发阶段时,在微信开放平台注册测试包的签名信息,上线时再修改成正式签名文件信息;或者你也可以修改IDE的默认签名文件。但是这些都不是很方便,如果微信开放平台能够像其他一些第三方服务供应商一样,针对一个应用提供两个或多个签名信息的注册,岂不快哉。
 •文档不清晰
 很多大型的第三方服务供应商只管功能的提供,不管文档的说明,甚至连Samples代码都写的乱七八糟的,导致我们开发人员在使用过程中连个完整的参考说明都没有,出了问题也无从下手,白白浪费很多不必要的时间和精力。

文章有些啰嗦,主要是阐述了自己这次在开发微信分享时遇到问题、分析问题并解决问题的过程,希望给大家一些借鉴。


推荐阅读
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • 非公版RTX 3080显卡的革新与亮点
    本文深入探讨了图形显卡的进化历程,重点介绍了非公版RTX 3080显卡的技术特点和创新设计。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 本文将详细介绍如何使用剪映应用中的镜像功能,帮助用户轻松实现视频的镜像效果。通过简单的步骤,您可以快速掌握这一实用技巧。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍如何在 Xcode 中使用快捷键和菜单命令对多行代码进行缩进,包括右缩进和左缩进的具体操作方法。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
  • 如何在WPS Office for Mac中调整Word文档的文字排列方向
    本文将详细介绍如何使用最新版WPS Office for Mac调整Word文档中的文字排列方向。通过这些步骤,用户可以轻松更改文本的水平或垂直排列方式,以满足不同的排版需求。 ... [详细]
  • 本文总结了在使用Ionic 5进行Android平台APK打包时遇到的问题,特别是针对QRScanner插件的改造。通过详细分析和提供具体的解决方法,帮助开发者顺利打包并优化应用性能。 ... [详细]
  • 理解存储器的层次结构有助于程序员优化程序性能,通过合理安排数据在不同层级的存储位置,提升CPU的数据访问速度。本文详细探讨了静态随机访问存储器(SRAM)和动态随机访问存储器(DRAM)的工作原理及其应用场景,并介绍了存储器模块中的数据存取过程及局部性原理。 ... [详细]
author-avatar
手机用户2602916275
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有