public class GameLoopThread extends Thread { private GameView view; private boolean running = false; public GameLoopThread(GameView view) { this.view = view; } public void setRunning(boolean run) { running = run; } @Override public void run() { while (running) { Canvas c = null; try { c = view.getHolder().lockCanvas(); synchronized (view.getHolder()) { if (c != null) { view.onDraw(c); } } } finally { if (c != null) { view.getHolder().unlockCanvasAndPost(c); } } try { sleep(10); } catch (Exception e) {} } } }
make this thread and then in your activity do something like this
@Override public void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); setContentView(new GameView(GameActivity.this)); }
then in GameViewClass do something like this
public class GameView extends SurfaceView { private SurfaceHolder holder; private GameLoopThread gameLoopThread; public GameView(Context context) { super(context); gameLoopThread = new GameLoopThread(this); holder = getHolder(); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; gameLoopThread.setRunning(false); while (retry) { try { gameLoopThread.join(); retry = false; } catch (InterruptedException e) { } } } @Override public void surfaceCreated(SurfaceHolder holder) { gameLoopThread.setRunning(true); gameLoopThread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } }); } @Override protected void onDraw(Canvas canvas) {
The important thing is that the thread manually calls the onDraw () method automatically, and that you lock the canvas, draw it, and then send it. If you don't need ultra-fast refresh rates, you might be better off doing something like this:
@Override public void onDraw(Canvas c) { c = this.getHolder().lockCanvas(); if (c != null) { //draw on canvas } if (c != null) { this.getHolder().unlockCanvasAndPost(c); } }
I just don't know if this last bit will work, never tested it. also, if you want to make your drawing outside the on draw method, you can start updating (drawing on the canvas) in the stream, and every time the onDraw method is called, check that Canvas is ready for it after. for example, your thread has a boolean value that, after the canvas is pulled, it is set to false, so the thread will draw a new one for you, but as soon as this is done, set the boolean value to true. in the ondraw method to check if a boolean value is true, and if it draws the canvas.