UI framework aplikasi Android didasarkan pada hierarki objek yang dimulai dengan View. Semua elemen UI akan melalui serangkaian pengukuran dan proses tata letak yang menyesuaikannya ke dalam area persegi panjang. Kemudian, semua objek tampilan yang terlihat dirender ke platform yang disiapkan oleh WindowManager saat aplikasi dibawa ke latar depan. UI thread aplikasi melakukan tata letak dan rendering ke buffer per frame.
SurfaceView
SurfaceView adalah komponen yang dapat Anda gunakan untuk menyematkan lapisan komposit tambahan dalam hierarki tampilan. SurfaceView menggunakan parameter tata letak yang sama dengan tampilan lain, sehingga dapat dimanipulasi seperti tampilan lainnya, tetapi konten SurfaceView bersifat transparan.
Saat merender dengan sumber buffer eksternal, seperti konteks GL atau decoder media, Anda perlu menyalin buffer dari sumber buffer untuk menampilkan buffer di layar. Dengan menggunakan SurfaceView, Anda dapat melakukannya.
Saat komponen tampilan SurfaceView akan terlihat, framework meminta SurfaceControl untuk meminta platform baru dari SurfaceFlinger. Untuk menerima callback saat platform dibuat atau dihancurkan, gunakan antarmuka SurfaceHolder. Secara default, platform yang baru dibuat ditempatkan di belakang platform UI aplikasi. Anda dapat mengganti urutan Z default untuk menempatkan platform baru di bagian atas.
Rendering dengan SurfaceView bermanfaat jika Anda perlu merender ke platform terpisah, seperti saat Anda merender dengan Camera API atau konteks OpenGL ES. Saat Anda merender dengan SurfaceView, SurfaceFlinger langsung membuat buffer ke layar. Tanpa SurfaceView, Anda perlu menggabungkan buffer ke platform di luar layar, yang kemudian digabungkan ke layar, sehingga rendering dengan SurfaceView menghilangkan pekerjaan tambahan. Setelah merender dengan SurfaceView, gunakan UI thread untuk berkoordinasi dengan siklus proses aktivitas dan melakukan penyesuaian pada ukuran atau posisi tampilan jika diperlukan. Kemudian, Hardware Composer menggabungkan UI aplikasi dan lapisan lainnya.
Platform baru adalah sisi produsen BufferQueue, yang konsumennya adalah lapisan SurfaceFlinger. Anda dapat mengupdate platform dengan mekanisme apa pun yang dapat memberi BufferQueue, seperti fungsi Kanvas yang disediakan platform, melampirkan EGLSurface dan menggambar di platform dengan GLES, atau mengonfigurasi decoder media untuk menulis platform.
SurfaceView dan siklus proses aktivitas
Saat menggunakan SurfaceView, render platform dari thread selain UI thread utama.
Untuk aktivitas dengan SurfaceView, ada dua mesin status terpisah tetapi saling bergantung:
- Aplikasi
onCreate
/onResume
/onPause
- Permukaan dibuat/diubah/dihancurkan
Saat aktivitas dimulai, Anda akan mendapatkan callback dalam urutan ini:
onCreate()
onResume()
surfaceCreated()
surfaceChanged()
Jika mengklik kembali, Anda akan mendapatkan:
onPause()
surfaceDestroyed()
(dipanggil tepat sebelum platform hilang)
Jika Anda memutar layar, aktivitas akan dibongkar dan dibuat ulang, dan Anda
akan mendapatkan siklus penuh. Anda dapat mengetahui bahwa ini adalah mulai ulang cepat dengan memeriksa
isFinishing()
. Aktivitas dapat dimulai/dihentikan dengan begitu cepat sehingga surfaceCreated()
terjadi setelah onPause()
.
Jika mengetuk tombol daya untuk mengosongkan layar, Anda hanya mendapatkan
onPause()
tanpa surfaceDestroyed()
. Platform
tetap aktif, dan rendering dapat dilanjutkan. Anda dapat terus mendapatkan
peristiwa Choreographer jika terus memintanya. Jika Anda memiliki layar
kunci yang memaksa orientasi yang berbeda, aktivitas Anda dapat dimulai ulang saat
perangkat tidak dikosongkan. Jika tidak, Anda dapat keluar dari layar kosong dengan
platform yang sama seperti sebelumnya.
Masa aktif thread dapat dikaitkan dengan platform atau aktivitas, bergantung pada hal yang ingin Anda lakukan saat layar kosong. Thread dapat dimulai/dihentikan pada aktivitas mulai/berhenti atau pada pembuatan/penghancuran platform.
Memulai/menghentikan thread pada mulai/berhenti Aktivitas berfungsi dengan baik dengan siklus proses
aplikasi. Anda memulai thread perender
di onResume()
dan menghentikannya di onStop()
.
Saat membuat dan mengonfigurasi thread, terkadang platform
sudah ada, terkadang tidak (misalnya, masih aktif setelah mengalihkan
layar dengan tombol daya). Anda harus menunggu platform dibuat
sebelum melakukan inisialisasi di thread. Anda tidak dapat melakukan inisialisasi dalam
callback surfaceCreate()
karena callback tidak akan diaktifkan lagi jika platform
tidak dibuat ulang. Sebagai gantinya, buat kueri atau cache status
platform, lalu teruskan ke thread perender.
Memulai/menghentikan thread pada pembuatan/penghancuran platform berfungsi dengan baik karena
platform dan perender secara logis
terjalin. Anda memulai rangkaian pesan setelah platform dibuat, yang
menghindari beberapa masalah komunikasi antar-rangkaian pesan; dan pesan yang dibuat/diubah
platform hanya diteruskan. Untuk memastikan rendering berhenti saat layar
kosong dan dilanjutkan saat layar tidak kosong, beri tahu Choreographer untuk berhenti memanggil
callback gambar frame. onResume()
melanjutkan callback jika
thread perender sedang berjalan. Namun, jika Anda menganimasikan
berdasarkan waktu yang berlalu di antara frame, mungkin ada celah besar sebelum
peristiwa berikutnya tiba; menggunakan pesan jeda/lanjutkan eksplisit dapat menyelesaikan masalah ini.
Kedua opsi, baik masa aktif thread terikat dengan Aktivitas
atau platform, berfokus pada cara thread perender
dikonfigurasi dan apakah thread tersebut dieksekusi. Masalah terkait adalah mengekstrak status
dari thread saat aktivitas dihentikan (di onStop()
atau
onSaveInstanceState()
); dalam kasus tersebut, mengikat masa aktif
thread ke aktivitas akan berfungsi paling baik karena
setelah thread perender digabungkan, status thread yang dirender dapat
diakses tanpa primitif sinkronisasi.
GLSurfaceView
Class GLSurfaceView menyediakan class helper untuk mengelola konteks EGL, komunikasi antar-thread, dan interaksi dengan siklus proses aktivitas. Anda tidak perlu menggunakan GLSurfaceView untuk menggunakan GLES.
Misalnya, GLSurfaceView membuat thread untuk rendering dan mengonfigurasi konteks EGL di sana. Status dibersihkan secara otomatis saat aktivitas dijeda. Sebagian besar aplikasi tidak perlu mengetahui apa pun tentang EGL untuk menggunakan GLES dengan GLSurfaceView.
Pada umumnya, GLSurfaceView dapat mempermudah penggunaan GLES. Dalam beberapa situasi, hal ini dapat mengganggu.