У меня была та же проблема: медленный рендеринг холста в контексте живых обоев.
Я согласен с другими, говоря, что вы не должны делать какие-либо тяжелые CPU / IO при рендеринге, например, при загрузке изображений, особенно в потоке пользовательского интерфейса.,
Однако есть еще одна вещь, на которую стоит обратить внимание.Вы запрашиваете перерисовку (mHandler.postDelayed (...)) ПОСЛЕ отображения кадра.Если вы хотите 30 кадров в секунду и, таким образом, запрашиваете перерисовку в (1000/30) 33 мс, это НЕ приведет к 30 кадрам в секунду.Почему?
Предположим, что для рендеринга всех ваших вещей на холст требуется 28 мс.После того, как это сделано, вы запрашиваете перерисовку через 33 миллис.То есть период между перерисовками составляет 61 мс, что равно 16 кадрам в секунду.
У вас есть два варианта решения:
1) Поместите mHandler.postDelayed (...)код начала метода drawFrame (...).Это выглядит нормально, но у него есть некоторые недостатки: если ваш фактический FPS очень близок к максимально возможному FPS на реальном устройстве - другими словами, поток пользовательского интерфейса все время занят рендерингом холста - тогда не будет времени дляпоток пользовательского интерфейса, чтобы делать другие вещи.Это не обязательно означает, что ваш LWP или домашний экран будут отставать, но вы (ваш LWP) можете начать пропускать некоторые сенсорные события (как это сделал мой LWP).
2) Лучшее решение - запустить отдельныйнить, когда поверхность создана, и передайте ей ссылку на SurfaceHolder.Сделайте рендеринг в этой отдельной теме.Метод визуализации в этой теме будет выглядеть так:
private static final int DESIRED_FPS = 25;
private static final int DESIRED_PERIOD_BETWEEN_FRAMES_MS = (int) (1000.0 / DESIRED_FPS + 0.5);
@Override
public void run() {
while (mRunning) {
long beforeRenderMs = SystemClock.currentThreadTimeMillis();
// do actual canvas rendering
long afterRenderMs = SystemClock.currentThreadTimeMillis();
long renderLengthMs = afterRenderMs - beforeRenderMs;
sleep(Math.max(DESIRED_PERIOD_BETWEEN_FRAMES_MS - renderLengthMs, 0));
}
}