Androidで使用されるSurfaceView
、したがってSurface
/Canvas
/Bitmap
システム全体への描画プロセスを理解するのに苦労しています。
私はすべての記事とAPIドキュメントページを読みました。これらはAndroid開発者サイトで見つけることができました。Androidグラフィックス、LunarLanderソースコード、および この質問 。
これらの陳述のどれが真実であり、どれが真実ではなく、そしてその理由を教えてください。
Canvas
には独自のBitmap
が付加されています。 Surface
には独自のCanvas
が付加されています。View
は同じSurface
を共有するため、同じCanvas
を共有します。SurfaceView
はView
のサブクラスであり、他のView
のサブクラスやView
自体とは異なり、描画する独自のSurface
を持っています。さらに1つの質問があります。
Surface
が存在する場合、なぜCanvas
クラスが必要なのですか。 Canvas
は、Surface
が実行できる作業を行うのに適していない状況の例を示します。以下にいくつかの定義を示します。
Surfaceは、画面に合成されるピクセルを保持するオブジェクトです。画面に表示されるすべてのウィンドウ(ダイアログ、フルスクリーンアクティビティ、ステータスバー)には、描画する独自のサーフェスがあり、Surface Flingerはこれらを正しいZオーダーで最終表示にレンダリングします。通常、サーフェスにはダブルバッファーレンダリングを行うために複数のバッファー(通常2つ)があります。アプリケーションは、アプリケーションの終了を待つことなく、最後のバッファーを使用してサーフェスフィンガーが画面を合成している間に次のUI状態を描画できます図。
ウィンドウは、基本的にはデスクトップ上のウィンドウのようなものです。ウィンドウのコンテンツがレンダリングされる単一のSurfaceがあります。アプリケーションはウィンドウマネージャーと対話してウィンドウを作成します。ウィンドウマネージャは、各ウィンドウにSurfaceを作成し、描画のためにアプリケーションに提供します。アプリケーションは、Surfaceで必要なものを何でも描画できます。 Window Managerにとっては、単なる不透明な長方形です。
ビューは、ウィンドウ内の対話型UI要素です。ウィンドウには単一のビュー階層がアタッチされており、ウィンドウのすべての動作を提供します。ウィンドウを再描画する必要があるときはいつでも(ビューがそれ自体を無効にしたためなど)、これはウィンドウのSurfaceで行われます。 Surfaceはロックされ、その中に描画するために使用できるCanvasを返します。描画トラバーサルは階層を下って行われ、各ビューのキャンバスを引き継いでUIの一部を描画します。完了すると、Surfaceのロックが解除されてポストされるため、描画されたばかりのバッファーが前景にスワップされ、Surface Flingerによって画面に合成されます。
SurfaceViewは、アプリケーションが直接描画するための専用のSurfaceを作成するViewの特別な実装です(通常のビュー階層の外側。ウィンドウの場合は単一のSurfaceを共有する必要があります)。この方法は、予想よりも簡単です。SurfaceViewは、ウィンドウマネージャーに新しいウィンドウを作成し、SurfaceViewのウィンドウの直後または前面にそのウィンドウをZオーダーするように指示し、それに合わせて配置するだけです。 SurfaceViewが含まれているウィンドウで表示される場所。サーフェスがメインウィンドウの後ろに(Zオーダーで)配置されている場合、SurfaceViewは、メインウィンドウの一部も透明にして、サーフェスが見えるようにします。
ビットマップは、一部のピクセルデータへの単なるインターフェイスです。ピクセルは、ビットマップ自体を直接作成するときにビットマップ自体によって割り当てられる場合があります。または、キャンバスを描画のためにSurfaceにフックする内部で発生するような、所有していないピクセルを指している場合もあります。 (ビットマップが作成され、Surfaceの現在の描画バッファーを指します。)
また、これが意味するように、SurfaceViewはかなり重いオブジェクトであることに注意してください。特定のUIに複数のSurfaceViewがある場合は、停止して、これが本当に必要かどうかを考えてください。 3つ以上ある場合、ほぼ間違いなく多すぎます。
ビットマップは、ピクセルのコレクションの単なるラッパーです。他の便利な機能を備えたピクセルの配列と考えてください。
Canvasは、すべての描画メソッドを含む単なるクラスです。それに精通している場合、AWT/SwingのGraphicsクラスに似ています。円やボックスなどの描画方法に関するすべてのロジックはCanvas内に含まれています。キャンバスはビットマップまたは開いているGLコンテナに描画しますが、将来、他のタイプのラスタに描画するために拡張できる理由はありません。
SurfaceViewは、Surfaceを含むビューです。サーフェスはビットマップに似ています(ピクセルストアがあります)。私はそれがどのように実装されているのかわかりませんが、画面表示に直接関連するもののための特別なメソッドを備えた何らかの種類のビットマップラッパーであると想像します(それが表面の理由です、ビットマップはあまりにも一般的です)。 SurfaceからCanvasを取得できます。これは、基になるビットマップに関連付けられたCanvasを実際に取得しています。
あなたの質問。
1.Canvasには、独自のビットマップが添付されています。 Surfaceには独自のCanvasが接続されています。
はい、キャンバスはビットマップ(または開いているGLパネル)で動作します。Surfaceは、ビットマップスタイルのピクセルストアに使用しているSurfaceで動作するキャンバスを提供します。
2.ウィンドウのすべてのビューは同じSurfaceを共有するため、同じCanvasを共有します。
いいえ。必要なだけサーフェスビューを作成できます。
3.SurfaceViewはViewのサブクラスであり、他のViewのサブクラスやView自体とは異なり、描画する独自のSurfaceを持っています。
はい。 ListViewと同様に、独自のListデータ構造を持つViewのサブクラスです。 Viewの各サブクラスは異なることを行います。