Auto.js icon indicating copy to clipboard operation
Auto.js copied to clipboard

在执行某些操作时脚本会崩溃(操作 opencv 时可稳定复现)

Open mslxl opened this issue 3 years ago • 4 comments

设备信息同 https://github.com/hyb1996/Auto.js/issues/678#issue-923751671 ,不确定该错误是否与设备相关

在执行某些操作时脚本会崩溃(同时与电脑的连接断开,无障碍服务也同时崩溃),但 Auto.js 程序没有崩溃,无任何报错信息。 此时表现有:

  • 与电脑连接的开关仍为打开状态,连接设备仍为 1,但实际上没有与电脑建立连接也不能直接重新连接,需要重新关闭再打开电脑连接的开关才能重新建立连接
  • 无障碍服务开关仍为打开状态,但无障碍服务实际未开启(与 https://github.com/hyb1996/Auto.js/issues/680 相似),需要重新关闭再打开无障碍服务开关

可稳定复现该问题的代码(某些操作也能出现该问题,但不能稳定复现,但都与复杂的图像处理有关):

importClass(org.opencv.core.Mat);
importClass(org.opencv.core.MatOfDMatch);
importClass(org.opencv.core.Scalar);
importClass(org.opencv.core.CvType);
importClass(org.opencv.core.MatOfKeyPoint);
importClass(org.opencv.features2d.BRISK);
importClass(org.opencv.features2d.BFMatcher);
importClass(org.opencv.features2d.Feature2D);
importClass(org.opencv.features2d.Features2d);
importClass(org.opencv.imgcodecs.Imgcodecs);
importClass(org.opencv.imgproc.Imgproc);

function detectFeature(img) {
    let mat = img.mat
    let detector = BRISK.create()
    let target = new Mat(mat.size(), mat.type())
    Imgproc.cvtColor(mat, target, Imgproc.COLOR_BGR2GRAY)
    Imgproc.Laplacian(target, target, mat.depth(), 3)

    let kp = new MatOfKeyPoint()
    let desc = new Mat()
    detector.detectAndCompute(target, new Mat(), kp, desc)
    desc.convertTo(desc, CvType.CV_32F)
    img.recycle()
    return {
        kp: kp,
        desc: desc
    }
}

function transArrayFromJava(javaObj){
    let arr = []
    for(let i = 0;i < javaObj.length;i++){
        arr.push(javaObj[i])
    }
    return arr
}

function main() {
    requestScreenCapture()
    let up = captureScreen() //随便找两张图就能蹦

    let re = up.clone()

    let kre = detectFeature(re)
    let kup = detectFeature(up)
    
    toastLog('pppppppppp')
    let matcher = new BFMatcher()
    toastLog('p1')
    let matchPoints = new MatOfDMatch()
    toastLog('p2')
    matcher.match(kup.desc, kre.desc, matchPoints) // 执行到这里突然就没了
    toastLog('p3')
    let dmatchs = transArrayFromJava(matchPoints.toArray())
    dmatchs = dmatchs.sort(function(a,b){return a.distance - b.distance})
    dmatchs = dmatchs.slice(0,5)
    toastLog('p4')
    let minX = Number.MAX_VALUE
    let minY = Number.MAX_VALUE
    for (let i = 0; i < dmatchs.length; i++) {
        const it = dmatchs[i]
        let point = kre.kp.toArray()[it.trainIdx]
        if(point.x < minX){
            minX = point.x
        }
        if(point.y < minY){
            minY = point.y
        }
    }
    toastLog('p5')
    core.clickXY(minX,minY)

    up.recycle()
}

main()

输出信息:

06-23 22:42:19.234 Script-0 Main [remote://f08870b2ab3cf9d390413e05280563af/test.js]/V: start operation[/data/user/10/org.autojs.autojspro/cache/remote_project/f08870b2ab3cf9d390413e05280563af/test.js] 
06-23 22:42:20.687 Script-0 Main [remote://f08870b2ab3cf9d390413e05280563af/test.js]/I: opencv initializing 
06-23 22:42:20.714 Script-0 Main [remote://f08870b2ab3cf9d390413e05280563af/test.js]/I: opencv initialized 
06-23 22:42:21.831 Script-0 Main [remote://f08870b2ab3cf9d390413e05280563af/test.js]/D: pppppppppp 
06-23 22:42:21.833 Script-0 Main [remote://f08870b2ab3cf9d390413e05280563af/test.js]/D: p1 
06-23 22:42:21.833 Script-0 Main [remote://f08870b2ab3cf9d390413e05280563af/test.js]/D: p2

就这些信息,甚至连错误或者运行结束的通知都没有

mslxl avatar Jun 23 '21 14:06 mslxl

首先这里有内存泄露,比如第一个函数的target就没有回收。 其实就是,Auto.js没有错误提示时,需要看logcat日志。如果你有adb,可以通过adb logcat -f 文件,来导出日志到文件;如果没有,可以在auto.js中运行shell('logcat -f /sdcard/log.txt')后,再运行你的代码。

clearw5 avatar Jun 24 '21 07:06 clearw5

那么应该怎么回收 Mat?


我用 java 写了相同的代码,正常运行,似乎不是脚本的问题。 这是 logcat

adb logcat : logcat.log

adb logcat *:E : logcatE.log

mslxl avatar Jun 24 '21 10:06 mslxl

目前看是一个空指针,如果Java代码没有问题的话,初步猜测和AJ重写Mat有关系。具体要用opencv对应版本的debug符号还原下调用栈

clearw5 avatar Jun 24 '21 13:06 clearw5

请问最近有修复计划吗?

mslxl avatar Jul 09 '21 23:07 mslxl