绘制大型位图时{n}非常慢nSyncAndDrawFrame

时间:2016-01-18 10:07:53

标签: android bitmap parallax

我想用多个大型位图优化视差滚动视图。在我的Nexus 5上,一切都很顺利,Traceview转储看起来像这样:

Smooth scrolling on Nexus 5

doFrame()方法使用~18 ms完成。

但是,在使用我的Nexus 7或Android 6仿真器(Genymotion)时,Traceview转储如下所示:

Very laggy rendering on Nexus 7

运行完全相同的应用程序时,nSyncAndDrawFrame方法现在需要大约300毫秒。

有趣的代码部分位于视差视图的onDraw()中:

for (int i = 0; i < parallaxConfigManager.getNumberOfLayers(); i++) {
            Bitmap layer = parallaxConfigManager.getLayer(i);
            float dx = (offset * parallaxConfigManager.getScrollSpeedFactorForLayer(i) * imageScaleFactor);
            int offset = Math.round(-parallaxConfigManager.getBoardOffset(i) + dx);
            srcRect.offsetTo(offset, 0);

            int realWidth = getRealWidth(srcRect, layer.getWidth());
            float scaleFactor = destRect.width() / (float) srcRect.width();
            if (realWidth < srcRect.width()) {
                destRect.left       = (int) (scaleFactor * Math.max(0, -srcRect.left));
                destRect.right      = destRect.left + (int) (scaleFactor * realWidth);
            }
            destRect.bottom = Math.min(screenHeight, (int) (scaleFactor * layer.getHeight()));

            canvas.drawBitmap(layer, srcRect, destRect, paint);

            destRect.left = 0;
            destRect.right = screenWidth;
        }

但是,这段代码足够快。缓慢的部分是Androids原生的nSyncAndDrawFrame()。

这可能是什么问题?有没有办法深入研究这个问题?现在这个方法是一个黑盒子,因为我看不到本机调用堆栈。

2 个答案:

答案 0 :(得分:0)

CollapsingToolbarLayout中遇到与大图像(1920x933)类似的行为后,我偶然发现了这个问题。探查者透露,拨打android.view.ThreadedRenderer.nSyncAndDrawFrame()的电话需要很长时间才能完成。

虽然降低图像分辨率(例如1280x622)可以消除这个问题,但是有一种方法可以完全避免这个问题。

将图像移动到drawable-nodpi文件夹,表示图像与分辨率无关。渲染延迟应该消失。

答案 1 :(得分:0)

就我而言,问题在于大图像。例如,对于背景,我有一个大小为 800x800 的图像,当我将此大小缩小到 400x400 时,问题就消失了。