【Android】二维码识别性能优化

背景:
发现公司App的二维码识别效率不高
一查,居然每次识别要耗差不多1s,好吧
可以好好优化下了。。
大部分的CaptureActivity.java都差不多
直接拿的原来的代码,用TraceView是看下函数运行时间。
和自己打log看下函数内各段函数执行时间就可以知道哪里比较慢

处理地方:

1.data数据横竖屏转换

对的,全世界都是这段代码,真没几个去优化下,但这里真的很慢,几百ms,不是开玩笑的。。

        Camera.Parameters parameters = mCamera.getParameters();
        Camera.Size size = parameters.getPreviewSize();
        int width = size.width;
        int height = size.height;

        byte[] rotatedData = new byte[mData.length];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                //**这里的计算有冗余,可以优化**
                rotatedData[x * height + height - y - 1] = mData[x + y * width];
            }
        }

然后就给我改了,这里真的很慢,一改,空间没有怎么增加,速度提高不少
如果你们喜欢,x * height 也可以改改,不过实测速度没提高多少,空间倒是要耗一些

        Camera.Parameters parameters = mCamera.getParameters();
        Camera.Size size = parameters.getPreviewSize();
        int width = size.width;
        int height = size.height;

        for (int y = 0; y < height; y++) {
            //**提前计算**
            int yw = y * width;
            int hym1 = height - y - 1;
            for (int x = 0; x < width; x++) {
                //**优化后快不少**
                mRotatedData[x * height + hym1] = data[x + yw];
            }
        }

PS: 每次只取截取框里的一小部分图像,其实是可以不用做完整张图片的横竖屏转换的。。但由于这里的横竖屏转换是YUV420SP的。可以考虑使用Android libyuv应用系列(二)libyuv的使用 去做转化)

2.所有要new的,全部都new 一次好了,减少内存抖动

            if (mSize == null){
                mSize = camera.getParameters().getPreviewSize();
            }
            if (mRotatedData == null) {
                mRotatedData = new byte[data.length];
            }

PS:内存抖动优化可以看看 Android性能优化之内存篇

3.onPreviewFrame走的是主线程

所以我做了个线程池,每次走线程来处理识别部分

        mThreadPool = Executors.newCachedThreadPool(); //这里每次只有一线程
        public void onPreviewFrame(final byte[] data, final Camera camera) {
            if (!previewing) return;
            mThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    if (!previewing) return;
                    // do your decode here
                }
            });
        }

释放camera时记得把线程池关了

    mThreadPool.shutdown();

4.在线程里面的log含有字符串拼接的话,就暂时关掉

当然大伙也可以考虑,替换 成 logger库,使用字符串格式化,
这样,关闭log的时候,字符串拼接就不会影响性能。

    Logger.d("test %s%s", "v", 5); // test v5

ps:参考 Log最佳实践

你可能感兴趣的:(Android)