I had the same problem: slow rendering of the canvas in the context of live wallpapers.
I agree with others, saying that you should not make any / io processor heavy when rendering, for example. uploading images, especially in the user interface stream.
However, there is one more thing you should note. You request a redraw (mHandler.postDelayed (...)) AFTER the frame has been rendered. If you want 30 frames per second, and thus you request a redraw (1000/30) 33 ms, then this will NOT result in 30 frames per second. Why?
Suppose that it takes 28 ms to transfer all of your materials to the canvas. After that, you request a redraw after 33 milliseconds. That is, the period between redraws is 61 ms, which is 16 frames per second.
You have two options for solving it:
1) Put the mHandler.postDelayed (...) code at the beginning of the drawFrame (...) method. It seems OK, but it has some drawbacks: if your actual FPS is very close to the highest possible FPS on a real device - in other words, the UI thread is busy all the time using canvas rendering - then there will be no time for the UI thread to do other things. This does not mean that your LWP or home screen will lag, but you (your LWP) can start to skip some touch events (as my LWP did).
2) The best solution is to start a separate thread when creating a surface and pass it a link to SurfaceHolder. Render in this separate stream. The rendering method in this thread will look like this:
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();
source share