微信小程序分享功能知识点

微信小程序分享功能知识点

  • 微信小程序分享功能知识点
    • 概览
      • 小程序与普通网页开发的区别
      • 小程序运行机制
        • 启动
        • 前台/后台状态
        • 小程序销毁
        • WXS响应事件的动机
    • 微信分享
      • 需求描述
      • 程序流程
      • FAQs
      • 同类小程序分享功能调研&猜想
      • 后端方案
      • 可能存在的bug
    • 参考文献

微信小程序分享功能知识点

最近开发微信小程序,记录一些重要的知识点。部分内容引用自微信官方文档。

概览

概览部分引用自《微信开放文档》1

小程序与普通网页开发的区别

网页开发的渲染线程和脚本线程是互斥的,因此长时间运行脚本可能导致页面失去响应。

在小程序中,渲染和脚本分别运行在不同的线程中。

逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的DOM API和BOM API。这导致一些常用库(jQuery、 Zepto 等),在小程序中是无法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,所以一些 NPM 的包在小程序中也是无法运行的1

小程序运行机制

启动

  • 热启动:假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台态的小程序切换到前台,这个过程就是热启动。
  • 冷启动:用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动,即冷启动。
  • 小程序没有重启的概念。

前台/后台状态

当用户点击右上角胶囊按钮关闭小程序,或者按了设备 Home 键离开微信时,小程序并没有直接销毁,而是进入了后台状态;

当用户再次进入微信或再次打开小程序,小程序又会从后台进入前台。

小程序销毁

需要注意的是:只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。

  • 当小程序进入后台,客户端会维持一段时间的运行状态,超过一定时间后(目前是5分钟)小程序会被微信主动销毁。
  • 当小程序占用系统资源过高,可能会被系统销毁或被微信客户端主动回收。
    • 在 iOS 上,当微信客户端在一定时间间隔内(目前是 5 秒)连续收到两次及以上系统内存告警时,会主动进行小程序的销毁,并提示用户 「该小程序可能导致微信响应变慢被终止」。
    • 建议小程序在必要时使用 wx.onMemoryWarning 监听内存告警事件,进行必要的内存清理

在调试过程中,安卓小程序在后台显示为与App类似的实际view,也就是说安卓用户可以手动销毁小程序,但在IOS系统上,小程序不显示。这一点还有待考证。

WXS响应事件的动机

由于视图层和逻辑层分开,有频繁用户交互的效果会比较卡顿。需要先将用户在视图层的event传进逻辑层,逻辑层处理完成之后通过setData()再传入视图层。需要两次通信+一次渲染。setData 渲染也会阻塞其它脚本执行,导致了整个用户交互的动画过程会有延迟。

因此WXS的使用的思路是减少通信的次数,让部分逻辑代码在视图层运行。

微信分享

需求描述

目前微信内分享常见三种形式,推荐到好物圈,朋友圈分享,微信好友/群分享

好物圈以插件形式存在,下文不具体涉及。

朋友圈分享,目前来看大多用画图来完成。由于微信没有提供直接分享朋友圈的接口,因此各路神通想出了:生成图片保存相册,转发朋友圈,扫图中小程序码的“三段跳”解决方案。这样在海报样式上能做更大的文章。比如插入用户信息,产品的信息,更酷炫的设计等等。

除了朋友圈分享这种方式,微信好友/群内分享也很常见。微信提供了很多API,其中包括监听页面内转发事件。在转发的过程中默认截取当前页面为转发图。如果想要得到更酷炫的转发图,也需要用到canvas画图来生成。

微信在Page中提供了onShareAppMessage的事件处理函数,监听用户点击页面内转发按钮。该函数返回一个对象,用于自定义转发内容:

{
     title: //标题
     path: //转发路径
     imgUrl: //自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径
}

因此,自然而然可以想到,在imgUrl上做文章。需要动态生成一张图片,并保存其url。到此,思路便比较清晰了:生成图片可用canvas绘图,并利用微信提供的API - wx.canvasToTempFilePath 得到本地图片url。

程序流程

分享图生成的画图方法在页面的生命周期中位置如下:

渲染层 逻辑层 画图方法 Start 初始化 等待数据 逻辑层 onLoad() send data to draw wx.getImageInfo() 处理网络图片 canvas 绘图 保存canvas图片 获取图片url 返回生成图片url send initial data 第一次渲染页面 notify 逻辑层 onReady() 逻辑层 Active onShareAppMessage 逻辑层 Active 弹出分享窗口 渲染层 逻辑层 画图方法

页面视图wxml文件中,button绑定onShareAppMessage()方法。同时设置canvas画布。利用wxss设置样式移到可见范围之外。

页面初次加载(onLoad)时,获取需要分享信息数据。可能同时包含有文字和图片信息。若图片来自网络,则会先下载到本地为画图备用。需要利用wx.getImageInfo(),获得该图片的本地url,在success回调函数中进行下一步处理画图。可以将该API包进一个Promise对象中返回,便于其他模块处理网络图片的链式调用和后续处理。

创建canvas上下文,利用canvas相关方法画图。关键的draw()方法有三个重要参数,第一个表示是否保留画布之前内容,第二个为绘制完的回调函数。在回调函数中调用wx.canvasToTempFilePath(),把当前画布指定区域的内容导出生成指定大小的图片。第三个为需要作用于的this对象。这一点很重要,因为需要在wx.canvasToTempFilePath()成功后,在其success回调中,将生成图片的url设置为page的全局变量。这样能在page作用域内,将生成图片的url设置到事件处理函数onShareAppMessage()当中。

FAQs

  1. 为什么不隐藏canvas,设置display:hidden

    隐藏会导致绘制失效

  2. 为什么在页面加载时就生成图片,而不是点击分享按钮后生成图片

    在页面事件onShareAppMessage()运行时,只有按规则返回具有对应参数的对象时,才能成功弹出分享到微信好友界面。(作者尝试通过Promise异步返回,但由于wx限制,若返回Promise对象便不能识别。)然而,在画图过程中调用的几个API均为异步方法,因此对于page页面的事件,无法做到先点击share button,触发onShareAppMessage()后,在该方法内调用其他异步绘图方法。这样无法得到新绘制图的url。

  3. 关于2真的做不到吗?我不是很相信

    具体见4、同类小程序分享调研

  4. 第一次点分享按钮图片不是我想要的,退出再点击一次就好了

    说明异步画图的url还没设置进去,用户就点击了分享按钮。这个时候显示默认的界面截图。退出后再点击的过程中,图片画好了,url已生成也设置进去了,正常显示。

    为了解决这个问题,可以添加一个page全局变量记录画图状态,已画完才显示button,否则不显示。

  5. 新绘制的图片中可以将多张图片合成在一起吗?

    能,在用户授权后,还可以添加用户头像和昵称信息

同类小程序分享功能调研&猜想

唯品会:有信息,点击分享button,加载约1秒,弹出Component组件。在组建内集和好物圈,微信好友,朋友圈三种分享方式。分别可点击,有不同效果。
猜想:虽然不知道源码,但share-button基本和其他页面元素一同加载出来。点击button 后有明显的1秒左右加载过程。笔者猜想canvas画图便设置在了这段时间内。注意这本质上也是先画图,再分享的过程。但在体验上完美地解决了问题2的整套动作。

网易考拉:无信息,只有一个网络图没处理

蘑菇街:有信息,在微信分享弹框内会有“。。。”等待加载。
猜想:有时主图加载时显示为视频,此时若点击过快会出现只有一张图的情况。笔者猜想是由后端生成的图片,直接返回url。点击过快可能信息还未返回,因此显示默认图片。

京东,拼多多,每日优鲜:有信息,点击过快只有主图
猜想:前端画图,未处理分享按钮,因此若点击过快没画完,则设置为主图。

苏宁易购:类似唯品会的“二级跳”,但是点击一级分享按钮后,过一会才会生成分享微信好友的按钮。这段时间内,大概率在进行canvas画图。画完图之后显示分享按钮。

后端方案

保险的做法,不受微信能力的限制。在后端画图,大体上需要提供两个API。

  • 画图并上传服务器,返回URL。
  • 通过刚才生成的URL拿到图片

存在的问题:后端画图无可厚非,不过在实际过程中,以Java为例,画图时间较长。如果加上来回前后端通信的时间,似乎时延是不可忍受的量级。同时由于该需求中需要显示的信息存在过期问题,缓存机制也将需要进一步考虑。

可能存在的bug

  • 人民币符号‘¥’在ios系统中显示可能出现问题

参考文献

  • 微信开放文档
  • 微信小程序前端生成图片用于分享朋友圈最终解决方案

  1. 微信开放文档 ↩︎ ↩︎

你可能感兴趣的:(微信小程序)