chenli
chenli
  • 发布:2020-08-05 12:06
  • 更新:2020-11-10 15:54
  • 阅读:3346

【报Bug】HX2.8.4 Android10 真机 uni.canvasToTempFilePath报错

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Mac

PC开发环境操作系统版本号: 10.15.6

HBuilderX类型: Alpha

HBuilderX版本号: 2.8.4

手机系统: Android

手机系统版本号: Android 10

手机厂商: OPPO

手机机型: OPPO Reno Ace

页面类型: vue

打包方式: 云端

项目创建方式: HBuilderX

示例代码:
context.translate(100, 100)  
context.rotate((180 * Math.PI) / 180)  
// context.drawImage结合其他绘画方法绘画后,再使用uni.canvasToTempFilePath方法都会报错  
// #ifdef APP-PLUS  
context.drawImage('../../static/uni@2x.png', 0, 0)  
// #endif  
// #ifndef APP-PLUS  
context.drawImage('../../static/logo.png', 0, 0)  
// #endif  
context.draw()

操作步骤:

context.drawImage结合其他绘画方法绘画后,使用uni.canvasToTempFilePath方法

预期结果:

使用uni.canvasToTempFilePath方法都会报错

实际结果:

context.drawImage结合其他绘画方法绘画后,使用uni.canvasToTempFilePath方法要正常

bug描述:

context.drawImage结合其他绘画方法绘画后,再使用uni.canvasToTempFilePath方法都会报错。
真机Android10 app-plus环境下 (OPPO Reno Ace和 三星S9 目前测试这两部真机有问题)自定义和标准基座都一样报错。
Android7(redmi 5A)是正常,模拟器android10也正常。
H5环境都正常
附件的可复现示例项目

TypeError: Cannot read property 'data' of undefined at view.umd.min.js:1

Android System WebView 85.0.4183.81
如手机上有安装Play商店的话,并且开启自动升级的情况,Android System WebView就会被自动升级。升级后uni.canvasToTempFilePath方法就会报错

2020-08-05 12:06 负责人:无 分享
已邀请:

最佳回复

DCloud_UNI_GSQ

DCloud_UNI_GSQ

新版webview内核有更严格的跨域限制,

HBuilderX alpha 2.9.0+ 已修复

其版本临时解决方案,本地路径使用插件(比如 https://ext.dcloud.net.cn/plugin?id=123)转换成base64

chenli

chenli (作者)

chenli

chenli (作者)

更新

chenli

chenli (作者)

更新

chenli

chenli (作者)

更新

jxtian

jxtian

这个报错复现的概率是多少,测试没有复现

测试项 结果
测试结果 未能复现
环境 hbuilderX 2.8.4
ios iPhone11
andriod oppo andriod5.1、华为andriod 10
<template>  
    <view class="about">  
        测试canvasToTempFilePath报错:  
        <canvas style="width: 1920px; height: 1080px;" canvas-id="firstCanvas" @error="canvasIdErrorCallback">  
        </canvas>  
        <button type="default" @click="exportImageForCanvas">导出图片</button>  
    </view>  
</template>  

<script>  
    export default {  
         onReady: function () {  
                var context = uni.createCanvasContext('firstCanvas')      

                context.setStrokeStyle("#00ff00")  
                context.setLineWidth(5)  
                context.rect(0, 0, 200, 200)  
                context.stroke()  
                context.setStrokeStyle("#ff0000")  
                context.setLineWidth(2)  
                context.moveTo(160, 100)  
                context.arc(100, 100, 60, 0, 20 * Math.PI, true)  
                context.fillStyle = 'rgb(200, 0, 0)'  
                context.moveTo(140, 100)  
                context.arc(100, 100, 40, 0, Math.PI, false)  
                context.fillStyle = 'rgb(200, 0, 0)';  
                context.moveTo(85, 80)  
                context.arc(80, 80, 5, 0, 2 * Math.PI, true)  
                context.fillStyle = 'rgb(200, 0, 0)';  
                context.moveTo(125, 80)  
                context.arc(120, 80, 5, 0, 2 * Math.PI, true)  
                context.arc(100, 100, 60, 0, 2 * Math.PI, true)  
                context.moveTo(140, 100)  
                context.arc(100, 100, 40, 0, Math.PI, false)  
                context.moveTo(85, 80)  
                context.arc(80, 80, 5, 0, 2 * Math.PI, true)  
                context.moveTo(125, 80)  
                context.arc(120, 80, 5, 0, 2 * Math.PI, true)  
                context.stroke()  

                // chenli (作者)  
                context.translate(100, 100)    
                context.rotate((180 * Math.PI) / 180)    
                // context.drawImage结合其他绘画方法绘画后,再使用uni.canvasToTempFilePath方法都会报错    
                // #ifdef APP-PLUS    
                context.drawImage('../../../static/uni@2x.png', 0, 0)  
                // #endif    
                // #ifndef APP-PLUS    
                context.drawImage('../../../static/logo.png', 0, 0)    
                // #endif    
                context.draw()  

            },  
            methods: {  
                canvasIdErrorCallback: function (e) {  
                    console.error(e.detail.errMsg)  
                },  

                exportImageForCanvas: function (){  
                    console.log('in exportImageForCanvas')  
                    uni.canvasToTempFilePath({  
                      x: 100,  
                      y: 200,  
                      width: 1920,  
                      height: 1080,  
                      destWidth: 1920,  
                      destHeight: 1080,  
                      canvasId: 'firstCanvas',  
                      quality: 0.5,  
                      success: function(res) {  
                        // 在H5平台下,tempFilePath 为 base64  
                        console.log(res.tempFilePath)  
                      } ,  
                      fail: function(err) {  
                        console.log("===canvasToTempFilePath err===",err);  
                      }  
                    })  
                }  
            }  
    }  
</script>  

<style>  
</style>  
  • chenli (作者)

    // #ifdef APP-PLUS      
    context.drawImage('../../../static/uni@2x.png', 0, 0)
    // #endif
    // #ifndef APP-PLUS
    context.drawImage('../../../static/logo.png', 0, 0)

    这个图片路径你有使用对吗,应该改为../../static才是正确的路径,把图片绘画出来。就会100%复现!

    2020-08-06 12:46

  • chenli (作者)

    修改你提供的代码为如下:android 10 oppo reno ace 100%复现


    <template>    
    <view class="about">
    测试canvasToTempFilePath报错:
    <canvas style="width: 1920px; height: 1080px;" canvas-id="firstCanvas" @error="canvasIdErrorCallback">
    </canvas>
    <button type="default" @click="exportImageForCanvas">导出图片</button>
    </view>
    </template>

    <script>
    export default {
    onReady: function () {
    var context = uni.createCanvasContext('firstCanvas')

    context.setStrokeStyle("#00ff00")
    context.setLineWidth(5)
    context.rect(0, 0, 200, 200)
    context.stroke()
    context.setStrokeStyle("#ff0000")
    context.setLineWidth(2)
    context.moveTo(160, 100)
    context.arc(100, 100, 60, 0, 20 * Math.PI, true)
    context.fillStyle = 'rgb(200, 0, 0)'
    context.moveTo(140, 100)
    context.arc(100, 100, 40, 0, Math.PI, false)
    context.fillStyle = 'rgb(200, 0, 0)';
    context.moveTo(85, 80)
    context.arc(80, 80, 5, 0, 2 * Math.PI, true)
    context.fillStyle = 'rgb(200, 0, 0)';
    context.moveTo(125, 80)
    context.arc(120, 80, 5, 0, 2 * Math.PI, true)
    context.arc(100, 100, 60, 0, 2 * Math.PI, true)
    context.moveTo(140, 100)
    context.arc(100, 100, 40, 0, Math.PI, false)
    context.moveTo(85, 80)
    context.arc(80, 80, 5, 0, 2 * Math.PI, true)
    context.moveTo(125, 80)
    context.arc(120, 80, 5, 0, 2 * Math.PI, true)
    context.stroke()

    // chenli (作者)
    context.translate(100, 100)
    context.rotate((180 * Math.PI) / 180)
    // context.drawImage结合其他绘画方法绘画后,再使用uni.canvasToTempFilePath方法都会报错
    // #ifdef APP-PLUS
    context.drawImage('../../static/uni@2x.png', 0, 0)
    // #endif
    // #ifndef APP-PLUS
    context.drawImage('../../static/logo.png', 0, 0)
    // #endif
    context.draw()

    },
    methods: {
    canvasIdErrorCallback: function (e) {
    console.error(e.detail.errMsg)
    },

    exportImageForCanvas: function (){
    console.log('in exportImageForCanvas')
    uni.canvasToTempFilePath({
    x: 100,
    y: 200,
    width: 1920,
    height: 1080,
    destWidth: 1920,
    destHeight: 1080,
    canvasId: 'firstCanvas',
    quality: 0.5,
    success: function(res) {
    // 在H5平台下,tempFilePath 为 base64
    console.log(res.tempFilePath)
    } ,
    fail: function(err) {
    console.log("===canvasToTempFilePath err===",err);
    }
    })
    }
    }
    }
    </script>

    <style>
    </style>

    2020-08-06 12:50

  • jxtian

    回复 chenli: 图片绘制出来的,文件在我的项目目录里要深一级

    2020-08-06 13:06

  • chenli (作者)

    回复 jxtian:

    可复现率百分百

    13:39:14.995 in exportImageForCanvas at pages/index/index.vue:119

    13:39:15.069 TypeError: Cannot read property 'data' of undefined at view.umd.min.js:1

    2020-08-06 13:40

jxtian

jxtian

用优测云的云真机测试这几个机型,没有复现,你可以先用其他版本避开这个问题,等出 2.8.4 正式版试试还有没有这个问题,感谢反馈。

三星 GALAXY S9

型号: SM-G9600
版本: 9
CPU: arm64-v8a
分辨率: 1440x2960
上市时间: 2018-03-16

OPPO Reno

型号: PCCM00
版本: 10
CPU: arm64-v8a
分辨率: 1080x2340
上市时间: 2019-10-15

OPPO Reno

型号: PCAM00
版本: 9
CPU: arm64-v8a
分辨率: 1080x2340
上市时间: 2019-04-10

OPPO Reno Z

型号: PCDM10
版本: 10
CPU: arm64-v8a
分辨率: 1080x2340
上市时间: 2019-05-01

chenli

chenli (作者)

@DCloud_UNI_家兴
试了很多云测手机都正常,云真机同款手机同个系统版本也一样正常,最后,终于排查到个别手机报错的原因!
手机里的Andriod System WebView版本
之前手动升级到版本号84.0.4147.111,这个版本会报错(报错信息前面截图的那样)。
现在手动卸载回到系统自带的版本号77.0.3865.92 就正常了。
另一部有问题的手机是同事的,他应该不会手动升级,三星 s9 plus(oneui 2.1 webview 版本暂时未知)。
这个是否是uni-app安卓原生适配bug,还是Android system webview的bug?这个需要你们安卓开发人员排查确认下。

  • jxtian

    andriod App 的 webview 是跟随系统的,升级可能会造成问题,至于那边的原因还需要排查。感谢反馈。

    2020-08-08 11:20

  • chenli (作者)

    回复 jxtian: 如手机上有安装Play商店的话,并且开启自动升级的情况,Android System WebView就会被自动升级。

    2020-09-02 18:42

l***@163.com

l***@163.com - 萌新,请多多关照

复议!2.8.6.20200814还是有这个问题。
手机 Redmi K20 pro MIUI 12.0.2
系统 Android10

  • chenli (作者)

    应用管理列表搜索下是否有Android System WebView

    如有搜索到看是否要操作卸载。有就卸载再尝试看下

    2020-08-17 16:57

  • l***@163.com

    回复 chenli: 真是这样,删掉就好了。。。

    2020-08-17 17:05

5***@qq.com

5***@qq.com

code:

var that = this  
                uni.canvasToTempFilePath({  
                    canvasId: 'myCanvas',  
                    success: (res) => {  

                    },  
                    fail: function() {  
                        //TODO  
                    }  
                })

方法:

canvasToTempFilePath

报错

TypeError: Cannot read property 'data' of undefined at view.umd.min.js:1  

状况一致,机型一致 三星 S9 ,机主最近有更新手机系统;

  • chenli (作者)

    应用管理列表搜索下是否有Android System WebView

    如有搜索到看是否要操作卸载。有就卸载再尝试看下

    2020-08-17 16:57

ThorUI_echo

ThorUI_echo - 开源项目: https://thorui.cn/doc

确实还有这个问题

  • chenli (作者)

    之前在你群里提过,后来才发现是webview的版本影响了。

    2020-08-20 22:12

  • 9***@qq.com

    回复 chenli: 那需要用户去手动删除这个配置吗

    2020-09-02 15:59

  • chenli (作者)

    回复 9***@qq.com: 不是配置,是Android System WebView被升级了,需要卸载【卸载就是恢复系统自带的版本】

    2020-09-02 18:41

9***@qq.com

9***@qq.com - uniapp开发者

oppo findx Android10 也会出现这个问题

chenli

chenli (作者)

@DCloud_UNI_家兴
Android System WebView 85.0.4183.81 问题依然存在,是否有安排排查适配问题?

d***@yunfanda.com

d***@yunfanda.com - 云帆达科技

希望官方快点解决这个问题!

ocean169

ocean169 - 陕西西安

   **  uni.canvasToTempFilePath({  
          destWidth: this.canvasWidth * this.pixelRatio,  
          destHeight: this.canvasHeight * this.pixelRatio,  
          canvasId: this.canvasId,  
          success: (res) => {  
            // 在 H5 平台下,tempFilePath 为 base64  
            console.log(res.tempFilePath)  
            this.handlePrizeImg(res.tempFilePath)  
          },  
          fail() {  
            console.log(2222)  
          }  
        }, this)**  

安卓华为p40 hbx - 2.9.3 直接进入fail ,有什么好的解决方案?

  • chenli (作者)

    生成失败的信息是什么?

    2020-11-10 17:28

  • ocean169

    回复 chenli: "errMsg": "canvasToTempFilePath:fail SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported."

    2020-11-10 17:39

  • chenli (作者)

    回复 ocean169: 建议你升级hx最新正式版本2.9.7看看。

    如果还有问题,可以把如下这两条信息发一下,方便他人排查问题:

    1、看一下软件列表里(需要取消隐藏系统应用)webview的版本号

    2、canvas上绘制的图片路径也提供一下(应该是远程链接图片地址)。

    一般这个是跨域问题,h5环境要注意,据说app是没有跨域。


    也可先尝试这个解决方案:先下载远程链接图片地址,使用生成的临时路径再绘制。

    2020-11-10 17:49

  • chenli (作者)

    回复 ocean169: Android System WebView的版本号

    2020-11-10 17:54

  • ocean169

    回复 chenli:2.9.7版本也试过了,同样的问题.目前初步解决方案,不管是本地图片路径还是远程链接图片地址,可以先下载,处理成base64格式,就不会存在这样的问题.

    2020-11-10 17:55

  • chenli (作者)

    回复 ocean169: 可以提供一下应用列表里搜索一下Android System WebView的版本号方便官方排查

    2020-11-10 17:56

  • Yitind

    回复 chenli: 华为emui 11 移除了Android System WebView (WebView 实现是 huawei WebView) ,系统应用列表显示huawei WebView

    2020-11-10 20:03

  • DCloud_UNI_GSQ

    目前已确认华为新版系统webview绘制本地图片有跨域问题,后续会进行修复,临时解决办法是使用插件市场的插件转换为base64

    2020-11-10 21:00

该问题目前已经被锁定, 无法添加新回复