Pustaka ini disederhanakan menggunakan pustaka Kotlin/JS dari program Kotlin/JVM dan Kotlin/Native. Itu membuatnya mengambil kode semudah mengambil data:
Zipline bekerja dengan menyematkan mesin JavaScript QuickJS di program Kotlin/JVM atau Kotlin/Native Anda. Ini adalah mesin JavaScript kecil dan cepat yang cocok untuk disematkan dalam aplikasi.
(Mencari Duktape Android?)
Mari kita buat game trivia yang memiliki pertanyaan segar setiap hari, meskipun pengguna kita tidak memperbarui aplikasinya. Kami mendefinisikan antarmuka kami di commonMain
sehingga kami dapat memanggilnya dari Kotlin/JVM dan mengimplementasikannya di Kotlin/JS.
interface TriviaService : ZiplineService {
fun games (): List < TriviaGame >
fun answer ( questionId : String , answer : String ): AnswerResult
}
Selanjutnya kita implementasi di jsMain
:
class RealTriviaService : TriviaService {
// ...
}
Mari kita hubungkan implementasi yang berjalan di Kotlin/JS ke antarmuka yang berjalan di Kotlin/JVM. Di jsMain
kami mendefinisikan fungsi yang diekspor untuk mengikat implementasi:
@JsExport
fun launchZipline () {
val zipline = Zipline .get()
zipline.bind< TriviaService >( " triviaService " , RealTriviaService ())
}
Sekarang kita dapat memulai server pengembangan untuk menyajikan JavaScript kita ke aplikasi apa pun yang sedang berjalan yang memintanya.
$ ./gradlew -p samples trivia:trivia-js:serveDevelopmentZipline --info --continuous
Perhatikan bahwa Gradle ini tidak akan pernah mencapai 100%. Itu sudah diduga; kami ingin server pengembangan tetap aktif. Perhatikan juga bahwa flag --continuous
akan memicu kompilasi ulang setiap kali kode berubah.
Anda dapat melihat manifes aplikasi yang disajikan di localhost:8080/manifest.zipline.json. Ini mereferensikan semua modul kode untuk aplikasi.
Di jvmMain
kita perlu menulis program yang mendownload kode Kotlin/JS kita dan memanggilnya. Kami menggunakan ZiplineLoader
yang menangani pengunduhan kode, caching, dan pemuatan. Kami membuat Dispatcher
untuk menjalankan Kotlin/JS. Ini harus berupa operator single-thread karena setiap instance Zipline harus dibatasi pada satu thread.
suspend fun launchZipline ( dispatcher : CoroutineDispatcher ): Zipline {
val manifestUrl = " http://localhost:8080/manifest.zipline.json "
val loader = ZiplineLoader (
dispatcher,
ManifestVerifier . NO_SIGNATURE_CHECKS ,
OkHttpClient (),
)
return loader.loadOnce( " trivia " , manifestUrl)
}
Sekarang kita membangun dan menjalankan program JVM untuk menggabungkan semuanya. Lakukan ini di terminal terpisah dari server pengembangan!
$ ./gradlew -p samples trivia:trivia-host:shadowJar
java -jar samples/trivia/trivia-host/build/libs/trivia-host-all.jar
Zipline memudahkan berbagi antarmuka dengan Kotlin/JS. Tentukan antarmuka di commonMain
, implementasikan di Kotlin/JS, dan panggil dari platform host. Atau lakukan sebaliknya: implementasikan pada platform host dan panggil dari Kotlin/JS.
Antarmuka yang dijembatani harus memperluas ZiplineService
, yang mendefinisikan satu metode close()
untuk melepaskan sumber daya yang disimpan.
Secara default, argumen dan nilai kembalian adalah nilai demi nilai. Zipline menggunakan kotlinx.serialization untuk menyandikan dan mendekode nilai yang melewati batas.
Tipe antarmuka yang diperluas dari ZiplineService
bersifat pass-by-reference: penerima dapat memanggil metode pada instance langsung.
Fungsi antarmuka mungkin ditangguhkan. Secara internal Zipline mengimplementasikan setTimeout()
untuk membuat kode asinkron berfungsi sebagaimana mestinya di Kotlin/JS.
Zipline juga mendukung Flow<T>
sebagai parameter atau tipe pengembalian. Hal ini memudahkan untuk membangun sistem reaktif.
Salah satu potensi hambatan dalam penyematan JavaScript adalah menunggu mesin mengkompilasi kode sumber masukan. Zipline mengkompilasi JavaScript menjadi bytecode QuickJS yang efisien untuk menghilangkan penalti kinerja ini.
Hambatan lainnya adalah menunggu kode diunduh. Zipline mengatasi hal ini dengan dukungan untuk aplikasi modular. Setiap modul masukan (Seperti standar Kotlin, serialisasi, dan pustaka coroutine) diunduh secara bersamaan. Setiap modul yang diunduh di-cache. Modul juga dapat disematkan dengan aplikasi host untuk menghindari pengunduhan apa pun jika jaringan tidak dapat dijangkau. Jika modul aplikasi Anda lebih sering berubah daripada perpustakaan Anda, pengguna hanya mengunduh apa yang diubah.
Jika Anda mengalami masalah kinerja saat runtime QuickJS, Zipline menyertakan profiler pengambilan sampel. Anda dapat menggunakan ini untuk mendapatkan perincian tentang bagaimana aplikasi Anda menghabiskan waktu CPU-nya.
Zipline mengimplementasikan console.log
dengan meneruskan pesan ke platform host. Ia menggunakan android.util.Log
di Android, java.util.logging
di JVM, dan stdout
di Kotlin/Native.
Zipline mengintegrasikan peta sumber Kotlin ke dalam bytecode QuickJS. Jika proses Anda terhenti, stacktrace akan mencetak file .kt
dan nomor baris. Meskipun ada JavaScript di bawahnya, pengembang tidak perlu berinteraksi dengan file .js
.
Setelah menggunakan antarmuka yang dijembatani, antarmuka tersebut harus ditutup agar objek rekan dapat dikumpulkan sampahnya. Hal ini sulit untuk dilakukan dengan benar, jadi Zipline meminjam ide dari LeakCanary dan secara agresif mendeteksi ketika panggilan close()
tidak terjawab.
Zipline mendukung tanda tangan EdDSA Ed25519 dan ECDSA P-256 untuk mengautentikasi perpustakaan yang diunduh.
Penyiapannya mudah. Hasilkan pasangan kunci EdDSA. Tugas untuk ini diinstal dengan plugin Zipline Gradle.
$ ./gradlew :generateZiplineManifestKeyPairEd25519
...
---------------- ----------------------------------------------------------------
ALGORITHM: Ed25519
PUBLIC KEY: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PRIVATE KEY: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
---------------- ----------------------------------------------------------------
...
Letakkan kunci pribadi di server build dan konfigurasikan untuk menandatangani build:
zipline {
signingKeys {
create( " key1 " ) {
privateKeyHex.set( .. .)
algorithmId.set(app.cash.zipline.loader. SignatureAlgorithmId . Ed25519 )
}
}
}
Letakkan kunci publik di setiap aplikasi host dan konfigurasikan untuk memverifikasi tanda tangan:
val manifestVerifier = ManifestVerifier . Builder ()
.addEd25519( " key1 " , .. .)
.build()
val loader = ZiplineLoader (
manifestVerifier = manifestVerifier,
.. .
)
Penandatanganan dan verifikasi menerima beberapa kunci untuk mendukung rotasi kunci.
Zipline dirancang untuk menjalankan kode organisasi Anda kapan dan di mana pun Anda menginginkannya. Itu tidak menawarkan kotak pasir atau isolasi proses dan tidak boleh digunakan untuk mengeksekusi kode yang tidak tepercaya.
Penting untuk diingat bahwa desain ini memberikan kepercayaan implisit pada:
Hal ini tidak melindungi terhadap segala jenis kompromi di atas.
Juga belum menyediakan mekanisme untuk melarang versi kode yang dapat dieksekusi yang lebih lama (ditandatangani) yang memiliki masalah umum.
Ada beberapa hal yang dapat Anda lakukan untuk memastikan hot-reload berjalan secepat mungkin:
kotlin.incremental.js.ir=true
untuk mengaktifkan kompilasi inkremental Kotlin/JS.org.gradle.unsafe.configuration-cache=true
untuk mengaktifkan cache konfigurasi Gradle.tasks.withType(DukatTask::class) { enabled = false }
untuk mematikan tugas Dukat jika Anda tidak menggunakan deklarasi tipe TypeScript.Zipline berfungsi di Android 4.3+ (API level 18+), Java 8+, dan Kotlin/Native.
Zipline menggunakan API yang tidak stabil dalam implementasinya dan sensitif terhadap pembaruan versi untuk komponen ini.
Komponen | Versi yang Didukung | Catatan |
---|---|---|
Kompiler Kotlin | 2.0.0 | Plugin compiler Kotlin belum memiliki API yang stabil. |
Serialisasi Kotlin | 1.6.3 | Untuk decodeFromDynamic() , encodeToDynamic() , dan ContextualSerializer . |
Coroutine Kotlin | 1.8.1 | Untuk transformLatest() , Deferred.getCompleted() , dan CoroutineStart.ATOMIC . |
Kami bermaksud menggunakan API stabil segera setelah tersedia.
Kami bermaksud menjaga agar host Zipline dan rilis runtime tetap dapat dioperasikan sehingga Anda dapat meningkatkan masing-masing secara mandiri.
Tuan Rumah Versi Zipline | Versi Runtime Zipline yang Didukung |
---|---|
0.x | Versi 0.x yang sama persis dengan host. |
1.x | Versi 1.x apa pun. |
Copyright 2015 Square, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Proyek ini sebelumnya dikenal dengan nama Duktape-Android dan mengemas mesin JavaScript Duktape untuk Android. Sejarah Duktape masih ada di repo ini begitu pula tag rilisnya. Versi yang tersedia tercantum di Maven Central.