Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

SurfaceView dan GLSurfaceView

UI kerangka aplikasi Android didasarkan pada hierarki objek yang dimulai dengan Tampilan . Semua elemen UI melalui serangkaian pengukuran dan proses tata letak yang menyesuaikannya dengan area persegi panjang. Kemudian, semua objek tampilan yang terlihat dirender ke permukaan yang disiapkan oleh WindowManager saat aplikasi dibawa ke latar depan. Rangkaian UI aplikasi melakukan tata letak dan rendering ke buffer per frame.

SurfaceView

SurfaceView adalah komponen yang bisa Anda gunakan untuk menyematkan lapisan komposit tambahan dalam hierarki tampilan Anda. SurfaceView menggunakan parameter tata letak yang sama dengan tampilan lain, sehingga dapat dimanipulasi seperti tampilan lainnya, tetapi konten SurfaceView transparan.

Saat Anda merender dengan sumber buffer eksternal, seperti konteks GL atau dekoder media, Anda perlu menyalin buffer dari sumber buffer untuk menampilkan buffer di layar. Menggunakan SurfaceView memungkinkan Anda melakukan itu.

Saat komponen tampilan SurfaceView akan segera terlihat, framework meminta SurfaceControl untuk meminta permukaan baru dari SurfaceFlinger. Untuk menerima callback saat permukaan dibuat atau dimusnahkan, gunakan antarmuka SurfaceHolder . Secara default, permukaan yang baru dibuat ditempatkan di belakang permukaan UI aplikasi. Anda dapat mengganti pengurutan Z default untuk menempatkan permukaan baru di atas.

Rendering dengan SurfaceView bermanfaat jika Anda perlu merender ke permukaan terpisah, seperti saat Anda merender dengan Camera API atau konteks OpenGL ES. Saat Anda merender dengan SurfaceView, SurfaceFlinger langsung menyusun buffer ke layar. Tanpa SurfaceView, Anda perlu menggabungkan buffer ke permukaan 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 daur hidup aktivitas dan buat penyesuaian pada ukuran atau posisi tampilan jika diperlukan. Kemudian, Hardware Composer memadukan UI aplikasi dan lapisan lainnya.

Permukaan baru adalah sisi produsen BufferQueue, yang konsumennya adalah lapisan SurfaceFlinger. Anda dapat memperbarui permukaan dengan mekanisme apa pun yang dapat memberi makan BufferQueue, seperti fungsi Canvas yang disediakan permukaan, memasang EGLSurface dan menggambar di permukaan dengan GLES, atau mengonfigurasi dekoder media untuk menulis permukaan.

SurfaceView dan siklus hidup aktivitas

Saat menggunakan SurfaceView, render permukaan dari thread selain thread UI utama.

Untuk aktivitas dengan SurfaceView, ada dua mesin status yang terpisah tetapi saling bergantung:

  • Aplikasi onCreate / onResume / onPause
  • Permukaan dibuat / diubah / dihancurkan

Saat aktivitas dimulai, Anda mendapatkan callback dalam urutan ini:

  1. onCreate()
  2. onResume()
  3. surfaceCreated()
  4. surfaceChanged()

Jika Anda mengklik kembali, Anda mendapatkan:

  1. onPause()
  2. surfaceDestroyed() (dipanggil tepat sebelum permukaan hilang)

Jika Anda memutar layar, aktivitas dirobohkan dan dibuat ulang dan Anda mendapatkan siklus penuh. Anda dapat mengetahui bahwa ini adalah restart cepat dengan memeriksa isFinishing() . Dimungkinkan untuk memulai / menghentikan aktivitas begitu cepat sehingga surfaceCreated() terjadi setelah onPause() .

Jika Anda mengetuk tombol daya untuk mengosongkan layar, Anda hanya mendapatkan onPause() tanpa surfaceDestroyed() . Permukaan tetap aktif, dan rendering dapat dilanjutkan. Anda bisa terus mendapatkan acara Koreografer jika terus memintanya. Jika Anda memiliki layar kunci yang memaksa orientasi yang berbeda, aktivitas Anda dapat dimulai ulang saat perangkat dilepas. Jika tidak, Anda bisa keluar dari layar kosong dengan permukaan yang sama seperti sebelumnya.

Umur utas dapat dikaitkan ke permukaan atau ke aktivitas, tergantung pada apa yang Anda inginkan terjadi saat layar menjadi kosong. Utas dapat mulai / berhenti baik saat aktivitas mulai / berhenti atau pada pembuatan / penghancuran permukaan.

Membuat utas mulai / berhenti pada Aktivitas mulai / berhenti berfungsi dengan baik dengan siklus hidup aplikasi. Anda memulai utas perender di onResume() dan menghentikannya di onStop() . Saat membuat dan mengonfigurasi utas, terkadang permukaan sudah ada, di lain waktu tidak (misalnya, masih aktif setelah mengaktifkan layar dengan tombol daya). Anda harus menunggu permukaan dibuat sebelum menginisialisasi di utas. Anda tidak dapat menginisialisasi di callback surfaceCreate() karena callback tidak akan diaktifkan lagi jika permukaan tidak dibuat ulang. Sebagai gantinya, buat kueri atau cache status permukaan, dan teruskan ke thread perender.

Memulai / menghentikan utas pada pembuatan / penghancuran permukaan bekerja dengan baik karena permukaan dan perender terjalin secara logis. Anda memulai utas setelah permukaan dibuat, yang menghindari beberapa masalah komunikasi interthread; dan pesan yang dibuat / diubah permukaannya hanya diteruskan. Untuk memastikan bahwa rendering berhenti saat layar menjadi kosong dan dilanjutkan saat kosong, beri tahu Koreografer untuk berhenti memanggil callback frame draw. onResume() melanjutkan callback jika thread perender sedang berjalan. Namun, jika Anda menganimasikan berdasarkan waktu yang berlalu di antara bingkai, mungkin ada celah besar sebelum acara berikutnya tiba; menggunakan pesan jeda / lanjutkan eksplisit dapat menyelesaikan masalah ini.

Kedua opsi tersebut, apakah umur utas terkait dengan Aktivitas atau permukaan, fokus pada bagaimana utas perender dikonfigurasi dan apakah itu dijalankan. Masalah terkait adalah mengekstrak status dari utas saat aktivitas dimatikan (di onStop() atau onSaveInstanceState() ); dalam kasus seperti itu, mengikat umur utas ke aktivitas bekerja paling baik karena setelah utas perender telah digabungkan, status utas yang dirender dapat diakses tanpa sinkronisasi primitif.

GLSurfaceView

Kelas GLSurfaceView menyediakan kelas pembantu untuk mengelola konteks EGL, komunikasi interthread, dan interaksi dengan siklus hidup aktivitas. Anda tidak perlu menggunakan GLSurfaceView untuk menggunakan GLES.

Misalnya, GLSurfaceView membuat utas untuk rendering dan mengonfigurasi konteks EGL di sana. Status dibersihkan secara otomatis saat aktivitas berhenti. Sebagian besar aplikasi tidak perlu tahu apa-apa tentang EGL untuk menggunakan GLES dengan GLSurfaceView.

Dalam banyak kasus, GLSurfaceView dapat mempermudah penggunaan GLES. Dalam beberapa situasi, hal itu bisa menghalangi.