当前位置:首页 > 技术分析 > 正文内容

Android 记录一次开发微信分享功能的吐槽与思考

ruisui883个月前 (02-03)技术分析24



在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代码都写的乱七八糟的,导致我们开发人员在使用过程中连个完整的参考说明都没有,出了问题也无从下手,白白浪费很多不必要的时间和精力。

文章有些啰嗦,主要是阐述了自己这次在开发微信分享时遇到问题、分析问题并解决问题的过程,希望给大家一些借鉴,同时也欢迎各位的关注,交流分享,彼此学习,共同进步。

关注同名微信公众号[技术鸟]


上谈【安卓】,下论【苹果】。以扯淡的态度,面对操蛋的技术,用幽默的语言,诠释开发的经典。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/1397.html

标签: wxentryactivity
分享给朋友:

“Android 记录一次开发微信分享功能的吐槽与思考” 的相关文章

Beta版Linux Mint“Xia”发行版22.1发布

IT之家 12 月 13 日消息,Beta 版 Linux Mint“Xia” 22.1 昨日(12 月 12 日)发布,新版本基于 Ubuntu 24.04,内核版本为 Linux 6.8,长期支持将持续到 2029 年,为用户提供可靠稳定的使用体验。新版本在软件包管理方面,主要弃用了传统的 ap...

vue3父子组件传对象,子组件访问修改父组件对象中的属性值

在Vue 3中,父子组件之间的数据传输通常通过props和emit进行。父组件可以通过props向下传递数据给子组件,子组件则可以通过emit向上通知父组件更新数据。如果需要在子组件中修改父组件对象中的属性值,可以使用一个名为ref的Vue 3新特性。以下是一个示例,演示了如何在Vue 3中实现父子...

10个实例小练习,快速入门熟练 Vue3 核心新特性(一)

作者:xuying 全栈修炼转发链接:https://mp.weixin.qq.com/s/_n2seDbbiO5hXQfuUGbUCQ前言Vue3.0 发 beta 版都有一段时间了,正式版也不远了,所以真的要学习一下 Vue3.0 的语法了。本篇文章总共分两部分,望小伙伴们认真阅读。下一篇:10...

HTML5+眼球追踪?黑科技颠覆传统手机体验

今天,iH5工具推出一个新的神秘功能——眼动追踪,可以通过摄像头捕捉观众眼球活动!为了给大家具体演示该功能的使用,我做了一个案例,供大家参考。实际效果如下:案例比较简单,就是通过眼动功能获取视觉焦点位置,剔除用户看中的牌。现在,舞台的属性中多了一个“启用眼动”的选项,另外,还多了一个“启用摄像头”的...

再来一波黑科技工具,低调使用

静读天下静读天下是一个特别优秀的电子书阅读器。它上面有多个在线书库,像古登堡计划,很多种优秀的书杂志,都可以下载来阅读。它还能智能识别章节功能,还支持外置的语音阅读功能。它支持多种文本格式,比如说txt,pdf,epub,mobi等等。为了便于阅读它还有10 种配色方式,还有夜间模式。不过免费版有广...

Gemini应用在Android上广泛推出2.0闪电模式切换器

#头条精品计划# 快速导读谷歌(搜索)应用的测试频道在安卓设备的双子应用中推出了2.0闪电实验功能,现已向稳定用户开放。双子应用通过谷歌应用运行,目前推出的15.50版本中,用户可通过模型选择器体验不同选项,包括1.5专业版、1.5闪电版和2.0闪电实验版。2.0闪电实验模型提供了更快的响应速度和优...