Programming with SurfaceView and thread strategy for game development
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
SurfaceView is an Android view that provides a dedicated drawing surface rendered on a separate thread from the UI thread. This makes it ideal for game development where you need to draw frames at 30-60 fps without blocking the main thread. The standard pattern is a game loop running on a dedicated thread that acquires the Canvas from the SurfaceHolder, performs all drawing operations, and then posts the frame. Understanding the SurfaceHolder.Callback lifecycle and frame timing is essential for building smooth Android games.
Basic SurfaceView Game Structure
The Game Thread
Delta Time for Smooth Movement
Fixed-FPS timing causes stuttering when frames are dropped. Use delta time to make movement frame-rate independent.
Handling Touch Input
Kotlin Version
Common Pitfalls
- Not joining the thread in
surfaceDestroyed: If the game thread is still running when the surface is destroyed,lockCanvas()returns null and the app crashes. Always setisRunning = falseand callgameThread.join()insurfaceDestroyedto ensure the thread stops before the surface is reclaimed. - Drawing on a null Canvas:
lockCanvas()can return null if the surface is not ready or is being destroyed. Always checkcanvas != nullbefore drawing. Using a try/finally block ensuresunlockCanvasAndPostis called even if drawing throws an exception. - Object allocation in the game loop: Creating objects (e.g.,
new Paint(),new Rect()) inside the game loop triggers garbage collection, causing frame drops and stuttering. Allocate reusable objects in the constructor and reuse them every frame. - Not using
synchronizedfor shared state: Touch events arrive on the UI thread while the game loop runs on its own thread. Reading/writing shared variables (player position, game state) without synchronization causes race conditions and visual glitches. Synchronize onsurfaceHolderfor both threads. - Fixed timestep without delta time: Using
Thread.sleep(16)for 60 FPS assumes each frame takes exactly 16ms. When a frame takes longer (e.g., during collision detection), movement stutters. Use delta time to decouple game logic speed from frame rate.
Summary
SurfaceViewprovides a separate drawing surface that can be rendered from a background thread- Implement
SurfaceHolder.Callbackto manage the surface lifecycle (created, changed, destroyed) - Use a dedicated game thread with
lockCanvas()/unlockCanvasAndPost()for the render loop - Use delta time (elapsed seconds) instead of fixed-step timing for smooth, frame-rate-independent movement
- Synchronize access to shared game state between the game thread and the UI thread (touch events)
Related reading
- ProgressDialog is deprecated.What is the alternate one to use?
- Proper practice for subclassing UIView?
- Proper Realm usage patterns/best practices?
- Proper usage of the Alamofire's URLRequestConvertible
- Proper use cases for Android UserManager.isUserAGoat?
- Proper use of beginBackgroundTaskWithExpirationHandler
- Proper way to exit iPhone application?
- Proper way to renew distribution certificate for iOS
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.