SurfaceView is-a View but is for different purpose and has its distinct characteristics in several aspects.
We don't use View directly but use its sub-class such as ImageView, TextView or customize View. Those subclass are called widget.SurfaceView have three primary usages: video playback, camera preview and 2D game. SurfaceView contains a SurfaceHolder which you can pass to MediaPlayer or Camera as display sink. (Another option is to pass a TextureView - which deserves a article for explaining ) MediaPlayer/Camera don't accept widget as display sink.
To utilize SurfaceView , you need to implement the SurfaceHolder.Callback and listen to the SurfaceCreate event. Only when SurfaceCreated is called, the underlying Surface is guaranteed to be safe to use, such as calling mediaPlayer.setDisplay(SurfaceHolder). For purpose other than video playback or camera, you will also need create an render thread, calling lockCanvas to get the Canvas , drawing to it and call unlockAndPost to post the change. More importantly, you need to synchronize the render thread and main thread.
However, to customize a View, all you need to do is to override the onDraw() method.(set aside for the measure, layout stuff). The drawing is always in main thread and the Canvas is offered to you from framework. Much less work.
To emphasis, in case you overlooked, View is updated in main thread while SurfaceView is updated in another thread.
Those are the main differences application developers should knows and cares about. However, there are a few more items that are not obvious unless you have looked into the framework internal.
SurfaceView has dedicate Surface buffer while all the view share one surface buffer that is allocated by ViewRoot. In another word, SurfaceView cost more resources.
SurfaceView can not be hardware accelerated (as of JB 4.4) while 95% operations on normal View are HW accelerated using openGL ES.
SurfaceView almost always goes to Hardware Composer and therefore power efficient.
Every SurfaceView introduce a new Window while all the widget reside in the same Application Window as created in the RootView when a Activity is instantiated.By default, the Window for SurfaceView has lower z-order than the Application Window. If so , how is the video still visible? It is because the corresponding area of the application window is marked as transparent region.
The time to draw is different. Normal view update mechanism is constraint or controlled by the framework. You call
in the UI thread or
in other thread to ask the framework to update your view. However, the view won't be updated until next VSYNC arrived. The easy way to understand VSYNC is to consider it as a timer that fires up every 16 ms for a 60 fps screen. This mechanism to sync up drawing with VSYNC was introduced in later Android to achieve better smoothness. However, for SurfaceView, you can render it anytime as you wish.
Check out other articles in Android UI Internal series