A2UI sedang beralih dari komponen yang berfokus pada web ke Android native. Perender Jetpack Compose baru untuk A2UI v0.9 memungkinkan developer merender UI dinamis yang dihasilkan LLM secara native. Alih-alih webview, aplikasi ini memanfaatkan framework aktor berbasis Coroutine, siklus proses class tertutup, dan integrasi Material 3 native.
Sesi ini membahas arsitektur baru, menjelaskan cara hierarki komponen berbasis server diterjemahkan menjadi node Compose reaktif, dan cara transisi tata letak bawaan menangani update struktural dengan lancar tanpa memblokir UI.
Transkrip
Halo semuanya, dan selamat datang di diskusi ini. Kita akan membahas cara membuat UI di aplikasi Android menggunakan library A2UI baru kami.
Saya Nick Butcher, product manager yang menangani Jetpack Compose.
Halo semuanya, saya Anton, engineer di tim Compose.
Saya sedang mengerjakan perender A2UI Jetpack Compose baru ini yang sangat ingin kami sampaikan kepada Anda hari ini.
Ya, kini dengan meningkatnya kemampuan AI, banyak aplikasi yang mencari cara agar AI dapat membantu Anda meningkatkan atau membangun pengalaman baru bagi pengguna.
Salah satu pengalaman menarik yang sedang dipertimbangkan beberapa orang adalah UI generatif, yaitu cara backend agentic membuat UI baru untuk pengguna Anda saat runtime, yang menurut kami sangat menarik.
Namun sayangnya, saat ini, banyak respons backend agen yang terjebak dalam dinding teks, seperti ini.
Jadi, berikut adalah contoh saat saya meminta agen untuk membuat fitur baru untuk memesan perjalanan.
Jadi, inilah perintahnya.
Seperti yang Anda lihat, jawabannya sebenarnya cukup bagus, tetapi terjebak dalam dinding teks yang tidak dapat saya gunakan untuk berinteraksi dengan mudah dan tidak terlihat seperti bagian lain dari aplikasi saya.
UI generatif memungkinkan Anda menciptakan pengalaman seperti ini, di mana Anda dapat membuat UI baru secara langsung sebagai respons terhadap input dinamis, sehingga membuka peluang untuk penyesuaian yang lebih banyak, atau pengalaman baru yang lebih beragam.
Jadi, berikut contoh UI yang dibuat menggunakan komponen native standar.
Jadi, Anda tentu dapat membangun pengalaman semacam ini sendiri, tetapi Anda harus menentukan format sendiri untuk pertukaran dengan backend, aliran peristiwa, dan fungsi Anda sendiri, dan sebagainya.
A2UI, singkatan dari Agent-to-UI, adalah protokol terbuka yang merupakan format JSON untuk menentukan semua hal ini.
Jadi, salah satu hal yang sangat saya sukai dari A2UI adalah formatnya yang deklaratif.
Agen hanya menampilkan representasi JSON dari UI yang akan dirender.
Fungsi ini tidak menampilkan kode apa pun yang perlu dieksekusi oleh klien Anda, yang dapat membuat Anda rentan terhadap kerentanan keamanan tertentu.
Hanya deklaratif.
Jadi, konsep lain apa yang perlu kita ketahui tentang A2UI?
Hanya dua konsep utama: katalog dan platform.
Katalog memiliki komponen seperti teks, tombol, baris, dan kolom yang dapat digunakan agen untuk membangun UI.
Katalog juga memiliki fungsi yang dapat digunakan agen untuk memformat teks, memvalidasi input pengguna, atau membuka URL.
Katalog adalah kontrak yang menentukan komponen dan fungsi yang didukung aplikasi Anda, dan agen hanya dapat membangun dengan komponen dan fungsi tersebut.
Artinya, seperti yang disebutkan Nick, agen tidak pernah mengeksekusi kode arbitrer di aplikasi Anda.
Gemini menyusun UI dari elemen penyusun yang Anda desain dan percayai.
Satu lagi konsep penting adalah platform.
Platform adalah satu bagian UI yang dikontrol agen, seperti contoh perencana perjalanan di slide ini.
Agen mendeskripsikan UI untuk platform dalam JSON menggunakan pesan protokol A2UI, seperti createSurface, updateComponents, dan menggunakan komponen serta fungsi yang ditentukan dalam katalog Anda.
Berbicara tentang katalog, katalog adalah konsep yang sangat mendasar dalam A2UI, karena mengontrol komponen yang dapat digunakan agen untuk membuat antarmuka.
Spesifikasi A2UI menentukan sesuatu yang disebut katalog dasar, yang merupakan kumpulan komponen umum yang dapat Anda gunakan untuk membuat sebagian besar UI.
Perender A2UI Jetpack Compose menyediakan implementasi katalog dasar menggunakan komponen Material 3.
Sebagian besar komponen katalog siap digunakan secara langsung.
Ada tiga komponen media: pemutar gambar, video, dan audio, tempat Anda perlu memasukkan library pilihan Anda.
Misalnya, Anda dapat memilih Coil untuk pemuatan gambar dan Media3 untuk pemutar video dan audio.
Namun, keunggulan sebenarnya dari A2UI dan library perender baru kami adalah Anda dapat membuat komponen dan katalog kustom Anda sendiri, serta sepenuhnya mengontrol apa yang dapat digunakan agen untuk membangun UI.
Kita akan membahas katalog nanti.
Oke, mari kita lihat tampilannya.
Jadi, mari kita beralih ke mesin demo.
Ini adalah aplikasi demo yang akan kita gunakan, dan kita akan membangun perender A2UI untuk menunjukkan kepada Anda betapa mudahnya.
Jadi, ini adalah serangkaian perintah, seperti yang dapat Anda lihat di chip kecil di tengah layar, yang dapat Anda kirim ke agen.
Jadi, jika kita mengklik salah satu perintah, perintah tersebut akan dikirim ke backend agen live yang sebenarnya, jadi semoga demonya berhasil, dan selain perintah, kita juga menambahkan beberapa petunjuk sistem.
Jadi, kita memberi tahu backend tentang protokol A2UI, tentang katalog komponen, dalam hal ini, katalog dasar yang kita gunakan di sini, yang dapat digunakan untuk membangun UI, dan kita memberikan beberapa contoh cara membangunnya.
Implementasi sesi chat di aplikasi demo kami sudah mengetahui cara mengekstrak pesan A2UI JSON mentah dari respons agen.
Jadi, dalam hal ini, agen membalas dengan beberapa teks yang diikuti dengan pesan protokol A2UI: createSurface, updateComponents.
Namun, saat ini, aplikasi kita hanya menampilkan JSON mentah ini dan belum merendernya sebagai UI.
Oke, sebelum kita membahas dan mengimplementasikan kodenya, jika kita bisa beralih kembali ke slide sebentar, mari kita mundur selangkah dan memberi tahu Anda tentang desain sistem, yang akan kita gunakan untuk mengimplementasikan ini.
Oh, ini dia.
Ya, jadi inilah rencananya.
Jadi, agen AI men-streaming respons ke aplikasi kita yang diterima oleh class ChatSession.
ChatSession mengekstrak pesan JSON A2UI mentah dari respons agen saat di-streaming dan meneruskannya ke pemroses pesan A2UI.
Pemroses pesan dikonfigurasi dengan parser yang mengonversi pesan JSON mentah tersebut menjadi representasi semantik.
Kemudian, pemroses akan memvalidasi pesan berdasarkan definisi katalog dan memetakannya ke serangkaian model platform.
Model platform, ini adalah hal-hal yang menentukan, tampilan UI dan, bagian UI yang dikontrol agen.
Model platform tersebut kemudian dirender sebagai Compose UI native menggunakan composable platform A2UI yang disediakan oleh library kami.
Komunikasi antara agen dan UI bersifat dua arah, sehingga saat pengguna berinteraksi dengan UI, tindakan dan error pengguna akan mengalir kembali ke agen.
Jadi, singkatnya, ada tiga elemen penyusun utama: katalog, pemroses pesan, dan platform.
Mari kita tulis kodenya.
Ya, mari kita buat jika kita bisa beralih mesin.
Oke, jadi langkah pertama adalah menambahkan dependensi.
Di sini Anda dapat melihat bahwa kami telah menyertakan dependensi A2UI Material 3, dan kami telah menyinkronkan project sehingga kita tidak perlu menunggu dan melihat Gradle.
Ini adalah dependensi tingkat teratas yang menentukan implementasi katalog dasar menggunakan komponen Material 3 tersebut, tetapi ada dependensi lain yang lebih mendetail di bawahnya.
Jadi, jika Anda tidak ingin menggunakan katalog dasar, yang akan kami jelaskan alasannya nanti, Anda dapat menggunakan katalog yang lebih terperinci.
Namun, tindakan ini akan menarik dependensi lainnya secara transitif.
Oke.
Jadi, ada tiga hal yang perlu diperhatikan.
Langkah pertama adalah menentukan katalog.
Jadi, di sini, dalam aplikasi kita, kita akan membuat fungsi factory untuk membantu membangun instance implementasi Material 3 dari katalog dasar.
Jadi, kita menggunakan fungsi library ini di sini, katalog dasar A2UI material, yang juga memiliki versi.
Seperti yang telah kami sampaikan, library ini menyediakan semua komponen umum yang Anda butuhkan, tetapi kami tidak ingin memaksa Anda menggunakan library pemuatan gambar atau rendering media tertentu, jadi Anda harus menyediakannya sendiri.
Jadi di sini, misalnya, Anton telah membuat wrapper ini di sekitar composable AsyncImage Coil, yang akan kita gunakan untuk memuat gambar, serta sedikit logika tambahan untuk demo kita guna mencari gambar dari Wikipedia.
Jadi, dengan sangat mudah, kita dapat memasukkan ini ke dalam komponen katalog.
Demikian pula, kami memiliki implementasi serupa untuk rendering, video, dan audio, yang akan menggunakan library Media3, untuk merendernya dengan ExoPlayer.
Jadi, dengan cara yang sangat sederhana seperti ini, kita dapat memasukkan komponen kita sendiri ke dalamnya.
Hal berikutnya yang dibutuhkan katalog adalah serangkaian fungsi standar.
Jadi, ini adalah fungsi yang dapat disediakan klien.
Sekali lagi, kami mengirimkan implementasi ini bersama dengan katalog dasar, tetapi kami perlu memberinya konteks, yang akan Anda gunakan untuk melakukan tindakan tertentu, seperti membuka URI jika pengguna mengetuk item.
Dengan demikian, langkah pertama kita telah selesai.
Kami telah membuat katalog.
Langkah berikutnya yang harus kita lakukan adalah menyiapkan Message Processor.
Jadi, inilah yang sebenarnya mengurai, respons, dan sebagainya.
Jadi, kita akan beralih ke model tampilan aplikasi, tempat kita akan membuat instance katalog yang telah kita siapkan sebelumnya, karena kita akan membutuhkannya.
Kemudian, kita akan membuat objek parser pesan, pemroses pesan, yang memerlukan akses ke katalog untuk memvalidasi respons terhadap komponen yang ingin kita gunakan.
Satu komponen lain yang perlu kita buat adalah parser, yang sebenarnya merupakan objek yang bertanggung jawab untuk melakukan penguraian pesan JSON saat pesan tersebut ditampilkan.
Jadi, di sinilah kita membuat objek ChatSession.
Jadi, seperti yang saya sebutkan sebelumnya, ChatSession sudah mengekstrak pesan A2UI mentah dari respons agen.
Dan saat setiap pesan A2UI baru sudah siap, callback onA2uiMessage ini akan dipanggil.
Jadi, kita hanya perlu meneruskan setiap pesan tersebut saat pesan tiba di pemroses.
Kita memanggil fungsi processInput, memberinya parser dan pesan.
Jadi, fungsi processInput mengurai setiap pesan, lalu mengantrekan pekerjaan agar prosesor memvalidasinya terhadap katalog dan memperbarui model permukaan.
Jadi, pemroses mengekspos kumpulan model platform aktif saat ini sebagai, activeSurfaces StateFlow.
ChatSession memiliki beberapa logika untuk menambahkan model platform ke status UI balasan agen yang akan dirender.
Jadi, kita cukup meneruskan StateFlow activeSurfaces ini sebagai parameter ke ChatSession.
Selain itu, seperti yang telah saya sebutkan, fungsi processInput mengantrekan pekerjaan untuk prosesor.
Namun, untuk benar-benar memulai pemrosesan, kita perlu meluncurkan coroutine di thread latar belakang.
Jadi, kita akan menggunakan cakupan model tampilan untuk itu dan menetapkan dispatcher default.
Dan dalam coroutine tersebut, kita hanya perlu memanggil processor.collectMessages.
Jadi, saat coroutine ini aktif, prosesor akan menangani pesan dari antrean pesan.
Jadi, satu hal lagi yang perlu kita lakukan adalah saat pengguna menghapus histori chat, kita juga perlu menghapus platform saat ini.
Jadi, kita panggil clearSurfaces.
Oke.
Jadi, kita telah menyelesaikan dua langkah pertama.
Kita telah membuat katalog, kita telah membuat pemroses untuk mengurai pesan.
Langkah berikutnya yang perlu kita lakukan adalah merender respons tersebut di UI.
Jadi, kita mengumpulkan permukaan tersebut saat diurai oleh parser.
Sekarang, di UI, kita akan meneruskannya dalam objek balasan agen ini dan kita akan melakukan iterasi pada objek tersebut.
Lalu, kita akan menggunakan composable platform A2UI ini dan meneruskan modelnya satu per satu saat kita melakukan iterasi untuk merender konten di tempat yang kita inginkan.
Satu catatan di sini adalah bahwa agen dapat memilih untuk menggunakan sesuatu seperti daftar jika memilih untuk menampilkan, Anda tahu, sejumlah besar konten.
Jadi, kita perlu menetapkan tinggi terbatas, yaitu tinggi maksimum pada komponen ini untuk memastikan komponen dirender dengan benar.
Dengan begitu, kita telah mengimplementasikan perender A2UI dasar.
Jadi, jika kita kembali ke aplikasi, meluncurkannya kembali, dan menekan perintah itu lagi, semoga agen akan menggunakannya untuk, ya, ini dia, merender UI yang sebenarnya.
Jadi, kita hanya perlu membuat kode tersebut secara langsung.
Ini bukan seperti trik sulap.
Tapi ya, ini menggunakan gambar asli.
Aplikasi ini menggunakan tab, dialog, pemilih tanggal, penggeser, dan semua komponen Material standar yang Anda gunakan untuk membangun aplikasi, bukan hanya menampilkan respons tekstual.
Karena ini adalah aplikasi sungguhan yang menggunakan komponen Material sungguhan, aplikasi ini melakukan hal-hal yang dilakukan komponen sungguhan.
Performa yang diberikan mirip dengan performa native.
Class ini melakukan hal-hal seperti merespons mode gelap di sini.
Ini adalah komponen Material.
Jadi, jika Anda memiliki composable tema Material luar yang warna, bentuk, tipografi, dan sebagainya telah disesuaikan, komponen ini akan mengambilnya sehingga terlihat seperti bagian aplikasi Anda yang lain.
Seperti yang disebutkan Nick, karena merupakan komponen Compose native, komponen ini memiliki semantik native.
Artinya, semua fitur aksesibilitas bawaan Compose didukung.
Jadi, hal-hal seperti TalkBack, penskalaan font, navigasi keyboard dapat langsung berfungsi.
Sekarang, karena Anda memanggil agen untuk membuat UI baru saat runtime, mungkin akan ada beberapa latensi.
Anda mungkin harus menunggu agen merespons.
Library melakukan apa yang dapat dilakukan untuk meminimalkan latensi ini.
Jadi, jika kita menggunakan jenis ini, kita akan memasukkan beberapa jeda untuk menunjukkan kepada Anda sedikit lebih lambat apa yang terjadi dan cara kita meminimalkannya.
Ya, karena mungkin perlu waktu beberapa saat bagi agen untuk menstreaming respons lengkap, kami menggunakan sesuatu yang disebut rendering progresif.
Jadi, begitu komponen root tiba, kami mulai menampilkan UI untuk platform tersebut.
Semua komponen penampung menampilkan placeholder pemuatan untuk turunannya jika turunan tersebut belum tiba.
Saat komponen turunan muncul, komponen tersebut akan dianimasikan menggunakan skema gerakan Material 3.
Oke.
Dan jika kita dapat beralih ke perintah berikutnya hanya untuk menampilkan fitur lain dari library.
Berikut adalah perintah lain yang meminta Gemini memesan meja untuk makan malam.
Di sini, agen memilih untuk menggunakan komponen penggeser ini, ya, agen menggunakannya.
Jadi, di sini Anda dapat melihat bahwa Anda dapat menarik dan berinteraksi dengan UI yang dibuat agen secara langsung.
Perhatikan bahwa tidak hanya angka pada komponen yang berubah, ada juga string format di bawah ini yang menghitungnya.
Seperti, beri tahu saya bahwa itu tidak melakukan perjalanan pulang pergi kembali ke agen hanya untuk memperbarui itu, bukan?
Ini adalah binding dua arah.
Jadi, komponen penggeser terikat ke model data dalam memori platform ini.
Semua komponen yang terikat ke jalur yang sama dalam model data akan otomatis diperbarui saat nilainya berubah.
Jadi, penggeser membaca nilai yang akan ditampilkan, dan saat saya menarik penggeser, penggeser akan menulisnya kembali ke model untuk memperbaruinya.
Jadi, semua ini terjadi secara lokal tanpa perlu bolak-balik ke agen.
Namun, kita juga dapat meminta agen untuk memperbarui data.
Jadi, mari kita buat menjadi 6 orang.
Perhatikan penggeser saat agen membalas.
Angkanya baru saja melonjak menjadi 6.
Mari kita lihat apa yang kita terima dari agen.
Alih-alih mengirimkan seluruh deskripsi baru UI, agen hanya mengirimkan satu pesan kecil updateDataModel yang memperbarui jalur untuk penggeser.
Karena penggeser terikat ke jalur tersebut, penggeser akan diperbarui di tempat.
Jadi, setiap model data platform dibuat berdasarkan status snapshot Compose, dan setiap properti komponen yang terikat ke jalur adalah status turunan.
Jadi, setiap kali pengguna atau agen memperbarui nilai dalam model data, semua komponen yang terikat ke nilai yang sama akan otomatis direkomposisi.
Oke.
Jadi, katakanlah kita ingin mengambil tindakan dan ingin menekan tombol reservasi, apa yang akan terjadi di sini, Anton?
Tidak ada yang terjadi saat ini.
Tombol ini mengirimkan tindakan, tetapi kita belum mengirimkannya ke agen.
Jadi, mari kita perbaiki.
Oke, jadi seperti halnya kita harus terhubung ke pemroses untuk memproses input, kita juga perlu terhubung ke output apa pun, tindakan apa pun yang dilakukan pengguna pada UI yang telah dibuat agen.
Jadi, untuk melakukannya, kita menggunakan flow outboundEvents yang diekspos oleh prosesor, dan mengumpulkan data di sini.
Jadi, ini adalah kesempatan Anda untuk memasukkan logika apa pun yang Anda inginkan berdasarkan, misalnya, saat pengguna mengetuk tindakan atau melakukan sesuatu dengan UI.
Jadi, di sini kita mengirim tindakan apa pun kembali ke agen untuk kemudian memutuskan apa yang harus dilakukan, tetapi pada tahap ini, Anda juga dapat memutuskan apakah akan memanggil backend Anda sendiri, atau membuka layar lain di aplikasi Anda, terserah Anda.
Jadi, Anton telah menghubungkannya, dan sekarang saat kita menekan tindakan konfirmasi reservasi, tindakan yang Anda lakukan akan dikirim kembali ke agen.
Dan di sinilah, Anda tahu, Anda bahkan dapat memutuskan untuk memanggil beberapa fungsi di backend.
Jadi, mari kita lihat apa yang sebenarnya kita kirim ke agen.
Jadi, ini adalah pesan tindakan A2UI.
Tindakan ini memiliki konteks, dan konteks tersebut berisi serangkaian properti yang diminta agen untuk dikirim saat tindakan ini dilakukan.
Jadi, saat saya mengklik tombol, properti tertentu ini akan di-resolve pada saat itu berdasarkan nilai saat ini dalam model data, dan itulah yang kami kirim ke agen.
Oke, dan sejauh ini agen tersebut cukup kooperatif dengan kita, tetapi kita sedang membahas AI di sini, dan AI bisa membuat kesalahan.
Jadi, mari kita lihat apa yang terjadi jika agen menampilkan kesalahan dalam UI yang dijelaskan kembali kepada kita.
Jadi, untuk perintah terakhir ini, kami meminta agen untuk membuat kesalahan agar kami dapat mendemonstrasikannya kepada Anda.
Mari kita lihat hasilnya.
Ya.
Seperti yang Anda lihat, salah satu komponen ditandai dengan error.
Dan sekarang masalahnya sudah diperbaiki.
Jadi, ini adalah loop koreksi mandiri agen.
Sebelum setiap komponen mencapai UI, kami memvalidasi pesan tersebut terhadap skema katalog.
Jika komponen tidak cocok dengan skema, komponen tersebut akan ditandai sebagai error.
Implementasi katalog dasar perender menunjukkan bahwa error tersebut diisolasi ke komponen tertentu, sementara UI lainnya masih ditampilkan.
Di balik layar, perender mengirimkan pesan error ke agen untuk memberi tahu agen apa yang salah.
Jadi, dalam kasus ini, kami mengirim pesan yang menyatakan bahwa jenis komponen yang tidak diketahui dan tidak ada, tidak ditemukan dalam katalog.
Kemudian, agen memiliki kesempatan untuk merespons dengan mengirimkan respons lanjutan yang memperbarui UI yang ada dan UI diperbaiki di tempat.
Ya.
Dalam penerapan katalog dasar Material saat ini, kami langsung menampilkan error, tetapi dalam komponen kustom, Anda dapat memutuskan untuk terus menampilkan indikator pemuatan untuk komponen jika ada error saat menunggu agen memperbaikinya.
Dengan cara ini, error mungkin sepenuhnya disembunyikan dari pengguna.
Dan berbicara tentang katalog dan komponen kustom, sejauh ini kita hanya menggunakan katalog dasar yang disediakan secara default, tetapi Anda tentu saja dapat menyesuaikannya dengan kebutuhan Anda sendiri.
Jadi, Anda dapat melihat bahwa saat kita menggunakan fungsi factory untuk membuat katalog, nilai default-nya adalah untuk semua komponen yang berbeda.
Jadi, Anda dapat dengan mudah memasukkan komponen Anda sendiri jika mau.
Jadi, misalnya, jika kita ingin memasukkan sistem desain kita sendiri di aplikasi dan tombolnya sendiri, kita dapat dengan mudah memasukkannya.
Jadi, kita cukup mengganti parameter ini saat membuat instance katalog, dan kita akan membuat definisi komponen ini.
Jadi, jika kita membuat class baru untuk mengimplementasikannya, Anda dapat melihat ada antarmuka di sini, katalog dasar A2UI dari tombol jenis.
Jadi, jika kita mengimplementasikannya, kita dapat memasukkan komponen kita sendiri.
Ya.
Jadi, karena kita mengganti komponen di katalog dasar, kita perlu mengimplementasikan antarmuka tombol katalog dasar A2UI ini.
Jadi, antarmuka ini sudah memiliki beberapa informasi tentang komponen seperti nama, deskripsi, dan skema properti.
Jadi, yang perlu kita lakukan untuk mengimplementasikan versi kita sendiri adalah mengimplementasikan fungsi composable ini.
Proses ini memerlukan beberapa parameter.
Jadi, parameter ini adalah nilai yang diterima dari agen setelah divalidasi.
Jadi, ini adalah hal-hal seperti ID turunan, yang merujuk ke komponen yang akan menjadi konten tombol.
Fungsi ini juga memiliki varian yang menjelaskan jenis tombol, definisi tindakan, dan beberapa parameter lainnya.
Dalam penerapan tombol di produksi, kita perlu menggunakan semua parameter ini, tetapi untuk tujuan demo, kita hanya memerlukan child dan action.
Jadi, mari kita implementasikan composable ini.
Oke, jadi dalam fungsi composable ini, kita akan memunculkan jenis tombol suka kustom kita sendiri di sini.
Seperti yang Anda lihat, kita dapat menggunakan parameter yang diberikan dan divalidasi oleh A2UI.
Jadi, misalnya, dalam fungsi onClick, kita dapat mengirimkan tindakan tersebut.
Kita dapat menggunakan jenis library DispatchAction ini dan meneruskan tindakan yang ditentukan A2UI.
Jadi, kita menggunakan tombol kita sendiri, tetapi kita masih ingin merender konten turunan, label, atau apa pun yang diputuskan untuk digunakan oleh agen.
Jadi, cara melakukannya adalah dengan menggunakan fungsi observeA2uiComponentState ini dan meneruskan childId ke fungsi tersebut untuk mendapatkan handle ke konten turunan yang harus dirender.
Kemudian, kita akan menggunakan fungsi composable A2uiComponent ini, lalu meneruskan status komponen turunan tersebut untuk merendernya.
Di sini, Anda dapat melihat bahwa kami hanya merender konten turunan jika berhasil dimuat, tetapi Anda juga dapat memiliki logika sendiri di sini jika konten sedang dimuat atau jika ada status error, Anda dapat memutuskan apa yang ingin ditampilkan.
Jadi, jika kita kembali ke salah satu contoh perintah di aplikasi demo dan sekarang kita mengganti tombolnya menggunakan, Anda tahu, tombol Material standar.
Sangat halus, semoga Anda bisa melihatnya.
Anda dapat melihat bahwa kami juga menggunakan tombol yang sangat disesuaikan di sini.
Keren, jadi itulah cara Anda, Anda tahu, mengganti beberapa jenis library, tetapi bagaimana jika Anda ingin memperluas library dengan jenis kustom Anda sendiri?
Kita dapat melakukannya dengan sangat mudah dengan menambahkan ke katalog itu sendiri.
Jadi, Anton akan membuat class baru di sini untuk mengimplementasikan komponen rating bintang.
Jadi, kita akan menambahkan sesuatu ke aplikasi untuk memungkinkan kita memberi rating restoran saat melakukan perjalanan hipotetis ini.
Jadi, karena kita tidak mengganti komponen yang ada, kita menggunakan antarmuka yang lebih umum ini, antarmuka komponen A2UI ini, yang, seperti yang Anda lihat, memiliki beberapa parameter yang perlu kita ganti.
Jadi, dua yang pertama adalah nama dan deskripsi.
Jadi, ini menjelaskan apa itu komponen kita dan fungsinya.
Hal ini sangat penting karena saat kita melakukan serialisasi katalog dan mengirimkannya ke backend untuk memberi tahu apa yang dapat digunakan untuk membangun UI, inilah yang akan digunakan agen untuk memutuskan apakah akan menggunakan komponen ini atau tidak saat merespons.
Jadi, Anda harus cukup deskriptif dan memberi tahu AI bahwa Anda tahu persis apa yang dilakukannya.
Properti berikutnya yang perlu kita ganti adalah properti properties ini, yang pada dasarnya memberi tahu apa yang pada dasarnya menentukan data yang ditangani komponen ini.
Jadi, kita akan membuat panel rating bintang agar Anda dapat memberi rating pada restoran, dan akan ada dua properti yang kita perlukan.
Nilai ini akan menjadi nilai, seperti jumlah bintang yang telah dipilih pengguna, yang akan menjadi properti yang dapat diubah yang dapat digunakan untuk berinteraksi dan diubah oleh pengguna, serta jumlah bintang maksimum.
Jadi, di sini kita dapat melihat Anton menggunakan properti jenis angka dinamis ini untuk nilainya.
Jadi, ini seperti jumlah bintang yang dipilih.
Yang juga memiliki deskripsi tersendiri yang memberi tahu agen kegunaan nilai ini.
Lalu, kita memiliki properti jenis statis, jadi kita hanya menggunakan properti A2UI jenis angka ini, untuk menentukan jumlah maksimum bintang yang dapat ditampilkan komponen ini.
Lalu, setelah menentukan kedua properti tersebut, kita hanya perlu menampilkannya.
Jadi, dengan mengganti properti properties ini, kita akan membuat daftar, dan menampilkannya.
Jadi, itulah cara Anda memberi tahu agen bahwa ini adalah hal yang ditangani komponen ini.
Ya.
Seperti yang disebutkan Nick, definisi properti ini digunakan untuk dikirim sebagai bagian dari skema katalog agar agen mengetahui cara menggunakan komponen ini.
Namun, definisi properti yang sama juga digunakan untuk mengekstrak nilai yang diketik saat runtime.
Jadi, hanya ada satu sumber tepercaya.
Jadi, mari kita lihat apa yang perlu kita lakukan untuk menerapkan hal ini.
Jadi, pertama, untuk mengakses properti max, karena properti max adalah properti statis, artinya agen mengirimkan nilainya secara inline di objek properti.
Jadi, untuk mengaksesnya, kita hanya perlu mendapatkannya dari objek properti dengan mereferensikannya menggunakan objek properti proper-max sebagai kunci.
Karena properti ini ditentukan sebagai angka, kita juga perlu mengonversinya menjadi int dan menetapkan default.
Hal berikutnya adalah properti nilai.
Karena properti nilai adalah properti dinamis, artinya properti ini merujuk ke sesuatu dalam model data.
Jadi, untuk mengaksesnya, kita perlu menggunakan API properties.bind dan meneruskan objek properti sebagai kunci sebagai parameter.
Jadi, fungsi ini akan menampilkan nilai saat ini yang disimpan dalam model data untuk properti ini dan juga berlangganan untuk update mendatang.
Jadi, setiap kali model data diperbarui, komponen ini akan otomatis merekomposisi.
Jadi, sama seperti sebelumnya, kita juga mengonversi ke int dan menetapkan beberapa default.
Satu hal lagi yang perlu kita lakukan adalah menyiapkan binding dua arah agar kita dapat mengubah rating.
Untuk melakukannya, kita menggunakan API bindUpdater.
Kita meneruskan objek properti yang sama yang menentukan properti, dan hasilnya, kita mendapatkan Jadi, bindUpdater menampilkan lambda yang memungkinkan kita mengubah nilai untuk properti ini dalam model data.
Sekarang kita siap memunculkan komponen rating bintang.
Oke.
Jadi, setelah menentukan komponen kustom sendiri, kita perlu menambahkannya ke katalog yang kita gunakan.
Jadi, sebelumnya, kita hanya menggunakan katalog dasar apa adanya.
Jadi, sekarang yang perlu kita lakukan adalah membuat katalog baru, yang akan mengambil semua katalog dasar dan menambahkan komponen kustom kita.
Jadi, katalog didefinisikan terdiri dari tiga hal.
ID, kumpulan komponen, dan kumpulan fungsi.
Untuk ID, kita akan menggunakan URI untuk menentukan, Anda tahu, katalog yang diidentifikasi secara unik serta versi yang sedang kita kerjakan.
Kemudian untuk komponen, kita akan mengambil semua komponen dari katalog dasar, lalu kita akan menggunakan operator add untuk menambahkan komponen kustom yang baru saja kita buat.
Lalu untuk fungsinya, kita akan menggunakan fungsi dari katalog dasar.
Jadi, kita telah memperluas katalog dasar untuk menambahkan jenis komponen kustom baru.
Lihat, membuat katalog kustom cukup mudah.
Jadi, agen mempelajari cara menggunakan katalog dari petunjuk sistem yang kita kirimkan kepadanya.
Jadi, karena kita telah membuat katalog kustom, mari kita perbarui juga petunjuk sistemnya.
Jadi, kita akan meneruskan objek katalog ke fungsi yang membangun petunjuk sistem.
Jadi, ini dia.
Jadi, hingga saat ini, kita mengirimkan definisi statis skema untuk katalog dasar karena kita menggunakan katalog standar ini.
Setelah memiliki katalog kustom, kita dapat membuat skema secara dinamis menggunakan fungsi toJsonSchemaString.
Jadi, tindakan ini akan membuat representasi JSON lengkap dari katalog ini, termasuk komponen rating bintang yang baru saja kita tambahkan.
Petunjuk sistem juga menyertakan beberapa contoh respons untuk agen.
Jadi, kami juga mengubah ID katalog di sini, sehingga contohnya merujuk ke katalog yang benar.
Oke.
Dengan demikian, kita telah memperluas katalog dasar untuk menambahkan jenis kustom kita sendiri.
Jadi, jika kita men-deploy ulang dan mencoba salah satu perintah ini, kita akan mendapatkan UI rating.
Lalu, agen akan membalas.
Di sini, Anda dapat melihat bahwa komponen bintang ini adalah komponen baru yang belum pernah dilihat agen hingga kita mengimplementasikannya sekarang.
Ini bukan bagian dari katalog dasar, kami baru saja membuatnya.
Saat saya mengklik bintang, lambda bindUpdater akan dipanggil dan nilainya akan diperbarui dalam model data.
Dan jika kita mengirimkan rating, kita dapat melihat tindakan dan konteks tindakan akan menyertakan nilai yang baru saja kita tetapkan.
Oke, sekarang kita kembali ke slide.
Jadi, kita telah membahas banyak hal dengan cukup cepat, tetapi semoga kami telah menunjukkan cara Anda dapat dengan mudah beralih dari agen yang merespons sebagai dinding teks menjadi agen yang benar-benar membuat UI native yang nyata.
Semoga kami telah menunjukkan kepada Anda bahwa integrasinya cukup mudah.
Ada tiga komponen utama yang perlu Anda lakukan: Anda perlu membuat katalog komponen, menerapkan beberapa logika penguraian, lalu merendernya di UI.
Dan semoga, kami telah menunjukkan bahwa library ini melakukan banyak hal untuk Anda secara langsung, seperti rendering progresif atau memvalidasi skema, loop koreksi mandiri, atau penanganan error, library ini melakukan banyak hal.
Dan semoga, kami telah menunjukkan dengan cukup cepat hari ini bahwa sangat mudah bagi Anda untuk menyesuaikannya.
Kami telah menunjukkan cara katalog dasar merespons Penerapan Tema Material jika Anda menggunakan Material, tetapi sangat mudah untuk memperluas atau mengganti komponen dalam katalog.
Namun, menurut saya, salah satu manfaat terbesarnya adalah jika Anda benar-benar membuat katalog sendiri.
Jika Anda ingin memiliki kontrol penuh atas UI yang dapat digunakan agen, Anda dapat membuat komponen kustom sepenuhnya.
Jika Anda ingin memberikan kebebasan penuh, Anda dapat memberikan komponen yang sangat dasar, seperti label teks dan tombol, lalu berkata, "Buat UI-nya".
Jika ingin kontrol lebih besar, Anda dapat membuat komponen yang lebih rumit dan berkata, "Ini adalah satu-satunya hal yang dapat Anda gunakan."
Jadi, Anda dapat mengontrol apa yang dapat dilakukan dan ditampilkan agen kepada pengguna.
Jadi, ini adalah library perender A2UI dan library Jetpack baru yang baru saja kami luncurkan.
implementation("androidx.compose.material3:material3-a2ui:1.0.0-alpha02")Saat ini masih dalam versi Alfa, Alfa 02 baru saja dirilis.
Jadi, ikuti link ini untuk melihatnya.
Kami memiliki dokumentasi di developer.android.com, serta beberapa contoh.
Kami memiliki contoh dasar yang menampilkan katalog dasar, serta contoh yang lebih rumit, dan aplikasi contoh JetPacker yang baru saja kami buat, yang akan Anda lihat lagi dalam keynote ADS yang akan hadir nanti hari ini, yang menunjukkan cara membuat komponen yang lebih rumit ini untuk mengontrol apa yang dilihat pengguna.
Seperti yang saya katakan, kami saat ini dalam versi Alfa, jadi ini adalah waktu yang tepat untuk mencobanya dan memberikan masukan serta permintaan fitur Anda, dan memberi tahu kami, misalnya, bagaimana Anda ingin menggunakannya, atau saya ingin menggunakannya jika bisa melakukan X atau Y.
Jadi, silakan lihat library dan beri kami masukan.
Dan itulah yang kami dapatkan.
Kami tidak sabar ingin melihat apa yang Anda dan agen Anda bangun dengan model ini.
Terima kasih banyak.
Terima kasih.