绘制大位图时非常慢的nSyncAndDrawFrame [英] Extremely slow nSyncAndDrawFrame when drawing large Bitmaps

查看:172
本文介绍了绘制大位图时非常慢的nSyncAndDrawFrame的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to optimize a parallax scrolling view with multiple large Bitmaps. On my Nexus 5, everything is smooth and the Traceview dump looks like this:

doFrame()方法使用〜18 ms来完成操作.

The doFrame() method uses ~18 ms to finish.

但是,当使用我的Nexus 7或Android 6仿真器(Genymotion)时,Traceview转储看起来像这样:

However, when using my Nexus 7 or an Android 6 Emulator (Genymotion), the Traceview dump looks like this:

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

The nSyncAndDrawFrame method now takes ~300 ms when running the exact same application.

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

The interesting code part is in onDraw() of the parallax view:

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;
        }

但是,此代码足够快.最慢的部分是Android的原生nSyncAndDrawFrame().

However, this code is fast enough. The slow part is in Androids native nSyncAndDrawFrame().

这里可能是什么问题?有没有一种方法可以更深入地研究这个问题?现在,此方法是一个黑匣子,因为我看不到本机调用堆栈.

What could be the problem here? Is there a way to look deeper into this problem? Right now this method is a black box, because I can not see the native call stack.

推荐答案

我在 CollapsingToolbarLayout 中遇到大图像(1920x933)的类似行为后,偶然发现了这个问题.探查器显示,对 android.view.ThreadedRenderer.nSyncAndDrawFrame()的调用需要很长时间才能完成.

I stumbled on this question after encountering similar behavior with a large image (1920x933) in a CollapsingToolbarLayout. The profiler revealed that calls to android.view.ThreadedRenderer.nSyncAndDrawFrame() were taking a long time to complete.

尽管将图像分辨率降低(例如降低到1280x622)可以解决该问题,但是有一种方法可以完全避免该问题.

Although reducing the image resolution (to 1280x622, for example) will eliminate the problem, there is a way to avoid the issue altogether.

将图像移到 drawable-nodpi 文件夹,这表示图像与分辨率无关.渲染滞后应该消失.

Move your image into the drawable-nodpi folder, which indicates that the image is resolution-independent. The rendering lag should disappear.

这篇关于绘制大位图时非常慢的nSyncAndDrawFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆