Vue.js实战——微信拍照时页面会被刷新的BUG定位_9
一、目标1、这几个月辛辛苦苦做出来,基于Vue.js和html5的项目里面,一直存在一个明显的BUG:在微信公众号拍照后,会出现概率重定向到当前页面(当前页面被刷新,或者叫做重新加载)。这两天的目标就是定位并解决这个bug,提高用户体验。2、基于之前的承诺,把精简后确实可用的微信公众号的源码放至GIT库(weixin_8),方便大家理解(涉及版权的LOGO和内部URL被屏蔽...
一、目标
1、这几个月辛辛苦苦做出来,基于Vue.js和html5的项目里面,一直存在一个明显的BUG:在微信公众号拍照后,会出现概率重定向到当前页面(当前页面被刷新,或者叫做重新加载)。这两天的目标就是定位并解决这个bug,提高用户体验。
2、基于之前的承诺,把精简后确实可用的微信公众号的源码放至GIT库(weixin_8),方便大家理解(涉及版权的LOGO和内部URL被屏蔽了),也请各位高手不吝赐教。
如果大家对微信公众号的编码感兴趣,下面简单介绍下代码逻辑及运行步骤:
1)还是按照前面的vue.js工程结构把微信公众号代码填补出来(结构见代码库或者之前的工程代码);
2)微信公众号的开发需要先去注册公众号,还需要搭建后台服务器和微信公众号平台对接,具体步骤见微信公众号的说明:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842;
3)上一步的OAuth2.0鉴权配置好以后,就可以调用微信的初始化接口进行初始化了,初始化的首要步骤是引入微信公众号的weixin-js-sdk,调用步骤相关文档参见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115,此处说下如何引入相关的js-api。依次执行如下命令:
npm install weixin-js-sdk@1.3.3
npm install axios
把微信的js-sdk和网络请求的sdk打包至项目中,这样就调用wx这个对象了,调用过程详见simple_biz.js。
二、步骤
1、初步分析了下拍照时的现象,发现整个公众号的页面被刷新了,而此处本身并没有加什么业务逻辑,只是单纯的调用了微信的拍照接口,所以断定是微信的BUG,现在就是看如何构造必现BUG的场景;
2、怀疑点1:拍照时内存溢出导致的。基于这个假设开始验证。在调用wx.chooseImage拍完照后,在wx.getLocalImgData获取本地图片Base64字符串时,把这个字符串push到数组1000000万次,这样内存肯定溢出了。经验证发现,在Android的微信版本中会因为Crash而直接关闭公众号页面;iPhone下则不会关闭页面,也不会被重定向;
let localData = base64 + res.localData;
let sum = 1000000;
let all = [];
while(sum>0){
sum+=-1;
all.push(localData);
}
param.success(all);
3、怀疑点2:项目代码中其它地方内存溢出导致的。把上述代码转至其它入口处,此处从系统中随意读取一张图片,然后push 1000000万次(图片转base64字符串的代码如下),发现Android微信页面还是Crash了,而IOS不会Crash,但是也不会重定向;
export function getBase64Img(url, callback) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
let img = new Image;
img.crossOrigin = 'Anonymous';
img.onload = function () {
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0);
let dataURL = canvas.toDataURL('image/png');
callback.call(this, dataURL);
canvas = null;
};
img.src = url;
}
4、怀疑点3:微信API Bug。但是拍照代码那处连续调用了微信的2个API:wx.chooseImage、wx.getLocalImgData,分别用于调用系统拍照功能,读取拍照后的图片Base64字符串。为了定界,分别加了2个alert语句,需要明确是哪个API有bug。经验证,概率重定向页面时,1个alert语句都没有打印出来,但因为成功调用到了系统拍照功能,第一个api还是起作用了,只是没有成功。所以能够基本确定就是微信平台wx.chooseImage api的BUG,非业务代码的问题;
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['camera'],
success: (res) => {
console.log("wx photo localIds:", res.localIds);
alert("successfully to take a picture.");
let imgParam = {
localId: res.localIds[0],
success: (res) => {
alert("successfully to get picture.");
let base64 = IMAGE_HEADER;
if (res.localData.indexOf(IMAGE_HEADER_SPLIT) > -1) {
base64 = "";
}
let localData = base64 + res.localData;
param.success(localData);
},
error: (error) => {
param.error("failed to get photo:", error);
}
};
wx.getLocalImgData(imgParam);
},
error: (error) => {
param.error("failed to get wx photo:", error);
}
});
5、基于4的结论,网上搜索了下wx.chooseImage被重定向的问题,找到了一个比较好的总结:http://blog.shaochuancs.com/android-upload-page-refresh/,简单总结下:微信调用另一进程的系统(浏览器)拍照组件后,浏览器因内存不足被Kill了,按照Android的加载机制,会重新加载整个页面。好吧,原来是Android底层的千年BUG,错怪微信了;
6、基于5的结论,想要进一步明确是不是因为我们项目中占有内存过多导致拍照进程被Kill掉了。于是写了weixin_8工程,代码中只保留了微信调用系统拍照的功能,结果很遗憾的发现:重定向的问题依然存在。好吧,这个BUG是无法解决了,但是中间的辛酸历程值得记录下来。
三、总结
1、该BUG在项目中很早就被发现,由于项目进度紧张,只是简单的初步定位了下,发现拍照后,选完图片,页面就被刷新了,而拍照动作完全都是调用微信的API,我并没有加任何可疑的业务逻辑,所以就断定是微信的BUG,然后就一直拖到现在;
2、找到原因后,同事和我自己心里都踏实了,后续考虑尽量减少项目拍照时的内存消耗来减少重定向的概率。
四、参考资料
[1]http://blog.shaochuancs.com/android-upload-page-refresh/
上一篇:Vue.js实战——ToggleSwitch组件介绍_8 下一篇:Vue.js实战——移植Html5 App为Android App_10
更多推荐
所有评论(0)