Search code examples
huawei-mobile-serviceshuawei-developersappgalleryappgallery-connect

What Should I Do If a HUAWEI Quick App Freezes When the canvas Component Draws an Image Using setInterval?


In my huawei quick app, the setInterval function is used to cyclically execute the code for using canvas. However, the quick app freezes when rendering an image on a Huawei phone. The code where the exception occurs is as follows:

click0() {
      this.speed = 0.3
      let ctx = this.$element('canvas').getContext('2d')
      setInterval(() => {
        this.num0 += 2
        this.noise = Math.min(0.5, 1) * this.MAX
        this._draw(ctx)
        this.MAX <= 200 && (this.MAX += 4)
      }, 20)
    },
    _draw(ctx) {
      this.phase = (this.phase + this.speed) % (Math.PI * 64)
      ctx.clearRect(0, 0, this.width, this.height)
      this._drawLine(ctx, -2, 'rgba(0, 194, 255, 0.2)')
      this._drawLine(ctx, -6, 'rgba(0, 194, 255, 0.4)')
      this._drawLine(ctx, 4, 'rgba(0, 194, 255, 0.6)')
      this._drawLine(ctx, 2, 'rgba(0, 194, 255, 0.8)')
      this._drawLine(ctx, 1, 'rgba(0, 194, 255, 1)', 4)
    },


Solution

  • You can first obtain the service provider by calling the API for querying device information to determine whether the quick app is supported by Huawei Quick App Loader.

    If so, set the time interval to longer than 100 ms. The sample code is as follows:

    onShow: function () {
                var that = this
                device.getInfo({
                    success: function (ret) {
                        console.log("handling success:", JSON.stringify(ret));
                        that.engineProvider = ret.engineProvider;
                    },
                    fail: function (erromsg, errocode) {
                        console.log("message:", erromsg, errocode);
                    }
                })
            },
            click0() {
                var that = this
                this.speed = 0.3
                console.log(that.engineProvider)
                let ctx = this.$element('canvas').getContext('2d')
                if (that.engineProvider === "huawei") {
                    setInterval(() => {
                        this.num0 += 2
                        this.noise = Math.min(0.5, 1) * this.MAX
                        this._draw(ctx)
                        this.MAX <= 200 && (this.MAX += 4)
                    }, 120)
                } else {
                    setInterval(() => {
                        this.num0 += 2
                        this.noise = Math.min(0.5, 1) * this.MAX
                        this._draw(ctx)
                        this.MAX <= 200 && (this.MAX += 4)
                    }, 20)
                }
            },
            _draw(ctx) {
                this.phase = (this.phase + this.speed) % (Math.PI * 64)
                ctx.clearRect(0, 0, this.width, this.height)
                this._drawLine(ctx, -2, 'rgba(0, 194, 255, 0.2)')
                this._drawLine(ctx, -6, 'rgba(0, 194, 255, 0.4)')
                this._drawLine(ctx, 4, 'rgba(0, 194, 255, 0.6)')
                this._drawLine(ctx, 2, 'rgba(0, 194, 255, 0.8)')
                this._drawLine(ctx, 1, 'rgba(0, 194, 255, 1)', 4)
            },
            _drawLine(ctx, attenuation, color, width) {
                ctx.save()
                ctx.moveTo(0, 0);
                ctx.beginPath();
                ctx.strokeStyle = color;
                ctx.lineWidth = width || 1;
                var x, y;
                for (var i = -this.K; i <= this.K; i += 0.01) {
                    x = this.width * ((i + this.K) / (this.K * 2))
                    y = this.height / 2 + this.noise * this._globalAttenuationFn(i) * (1 / attenuation) * Math.sin(this.F * i - this.phase)
                    ctx.lineTo(x, y)
                }
                ctx.stroke()
                ctx.restore()
            },
    

    For Details,pls kindly refer:

    Introduction to the canvas API

    Quick app materials