Android applicazioni con seed
Questa guida descrive come utilizzare la corrente Android seed piattaforma e quadro. Il supporto implementato combina a seed biblioteca (mobile), un Android ospite basato su Gradle/Kotlin/CMake e un bridge JNI che carica il file nativo seed biblioteca.
Stato attuale: Android è la piattaforma mobile attiva. Il quadro prevede a superficie Canvas mantenuta guidata da comandi frame, input di base, ciclo di vita, inserti, metriche dello schermo e multi-ABI imballaggio. Non è ancora completo kit di strumenti widget.
Cosa è supportato
android-arm64come eseguito mobile ABI;android-x86_64rimane solo come target build/link compatibile;- Android API 37, strumenti da riga di comando 22.0, build-tools 37.0.0, Gradle 9.5.0,
AGP 9.3.0 e NDK
27.2.12479018come base; - shared/static seed librerie caricate da un Android ospite;
seed_mobile_entryingresso singolo e ganci del ciclo di vita;- cornici con un colore di sfondo, fino a 256 rettangoli, 32 elementi di testo e 128 nodi semantici;
- tocco, tasti e
InputConnection.commitTextattraverso una coda delimitata; - inserzioni delle finestre, focus, pressione della memoria, densità e directory private;
- un contesto opzionale per generazione
Activitye uscita PCM stereo tramite OpenSL ES con pause/resume; - esecuzione in AVD e installation/launch tramite
adb; - development/release firma ed esecuzione convalidate sul dichiarato Motorola Android 15/API 35 ARM64 fetta del dispositivo fisico.
Quanto segue non è una dichiarazione di supporto attuale: un catalogo completo di widget, TalkBack per il dispositivo fisico, completo IME selection/composition, modellazione del testo, ricarica a caldo, un'ampia matrice di dispositivi, pubblicazione in negozio o preparazione alla produzione.
Architettura
seed app (.sd)
│ integrated build: .so + .a per ABI
▼
libseed_app.so ─► JNI bridge (preferred packaged dependency)
libseed_app.a ─► separate static artifact
│ C ABI
▼
JNI bridge + SeedSurfaceView
│
▼
Activity Android / Canvas / adb / Gradle
Il seed l'applicazione non sostituisce ancora Activity. Il Android l'host rimane responsabile di processo, finestra, Canvas, JNI e integrazione con l'SDK. Il mobile fornisce le importazioni portatili della sezione implementata e deve essere utilizzata solo con un file Android bersaglio.
Requisiti
Devi avere:
- macOS Apple Silicon per la matrice ARM64 attualmente validata;
- JDK 17;
- NDK
clang,adb, Android CLI/sdkmanager,aapt2, Gradle ed emulatore; - un
arm64-v8aAVD oadb-ARM64 autorizzato Android dispositivo.
Il programma di installazione ufficiale del progetto utilizza $HOME/Android/Sdk, non richiede sudoe installa la baseline completa:
./seed mobile android setup
./seed mobile android doctor
Opzioni utili:
./seed mobile android setup --sdk "$HOME/Android/Sdk" --start
./seed mobile android setup --skip-avd
./seed mobile android setup --dry-run
Utilizzare --api, --abi, --image-flavor, --ndk, --avd, e --device per personalizzare l'installazione. --skip-gradle lascia l'installazione di Gradle all'utente. Per utilizzare un NDK diverso dalla linea di base, dichiarare esplicitamente SEED_ANDROID_NDK_REVISION e confermare la compatibilità con il progetto.
La diagnostica dovrebbe mostrare Android 37.0, build-tools 37.0.0, Gradle 9.5.0, platform-tools, NDK e API 21 sysroot di aarch64-linux-android e x86_64-linux-android:
./seed mobile android doctor
Esercitazione 1: prima applicazione
Crea app.sd:
fn main() -> i64 {
0
}
pub fn seed_mobile_entry() -> i64 {
0
}
Crea un host copiando il modello con versione:
cp -R seed/compiler/llvm/mobile/android my-android
Compila entrambe le ABI, esegui lo stage e genera l'APK:
./seed mobile android build app.sd my-android \
--package-name seed_app \
--application-id com.example.seedapp \
--package
Il comando produce libseed_app.so e libseed_app.a per arm64-v8a e x86_64, copia gli artefatti in my-android/app/src/main/jniLibs/, associa l'oggetto condiviso seed come dipendenza bridge JNI in pacchetto ed esegue assembleDebug; l'archivio rimane disponibile separatamente per i consumatori nativi. Il file my-android/seed-android.properties registra il nome nativo e l'ID dell'applicazione utilizzati dai comandi successivi.
Tutorial 2: disegnare uno schermo
Importa la libreria mobile Android nel codice dell'applicazione. Un esempio completo è in compiler/llvm/tests/mobile/android_framework.sd. Il callback del frame riceve larghezza, altezza e tempo in nanosecondi:
use "mobile"
pub fn seed_mobile_entry() -> i64 { 0 }
pub fn seed_mobile_on_frame(width: i32, height: i32, time_nanos: i64) {
mobile.frame_clear()
mobile.frame_color(4278190335 as i64) // ARGB: opaque blue
mobile.frame_rect(1000, 1000, 2000, 2000, 4294902015 as i64)
mobile.frame_text("Hello, Android", 1500, 4500, 2400, 4294967295 as i64)
}
Le coordinate e la dimensione del carattere sono espresse in millipixel. I colori sono numeri interi ARGB. L'host limita ciascun frame a 256 rettangoli, 32 elementi di testo, 128 nodi semantici e 256 UTF-8 byte per etichetta o elemento. Il testo è disegnato da Android tela; la selezione dei caratteri e la modellazione avanzata non fanno ancora parte del contratto.
Tutorial 3: Consumo di tocco, tastiera e IME
La libreria mantiene una coda delimitata di 128 eventi. Leggere i campi prima di rimuovere un evento:
use "mobile"
fn read_input() {
while mobile.input_available() {
let kind = mobile.input_kind()
let a = mobile.input_a()
let b = mobile.input_b()
let c = mobile.input_c()
// kind 1: touch; a=action, b=x in millipixels, c=y in millipixels.
// kind 2: key; a=action, b=Android key code, c=Unicode code point.
// kind 3: text committed by the IME.
if kind == 3 {
let length = mobile.input_text_length()
// input_text_byte(index) exposes the committed text's UTF-8 bytes.
let _ = length
}
mobile.input_pop()
}
}
input_pop deve essere chiamato una volta per evento. Se i produttori superano la capacità, la coda conserva gli eventi più recenti. La regione di selezione e composizione non è ancora esposta.
Esercitazione 4: Ciclo di vita e risorse
Definire solo gli hook necessari. Vengono eseguiti sul thread Activity e non devono bloccare, conservare oggetti JNI o creare attività senza un gruppo strutturato:
pub fn seed_mobile_on_create() {}
pub fn seed_mobile_on_start() {}
pub fn seed_mobile_on_resume() {}
pub fn seed_mobile_on_pause() {}
pub fn seed_mobile_on_stop() {}
pub fn seed_mobile_on_destroy() {}
seed_mobile_entry è protetto contro l'esecuzione ripetuta nello stesso processo; la ricreazione di Activity non riavvia l'applicazione. La distruzione annulla i lavori in sospeso sul ponte; la morte del processo è il confine finale della pulizia.
Le applicazioni con funzionalità persistenti tra frame possono essere esportate seed_mobile_context_create, seed_mobile_context_on_event, seed_mobile_context_on_frame, e seed_mobile_context_destroy. L'host mantiene al massimo un contesto per generazione di Activity, interrompe l'inoltro dei callback quando questa generazione viene invalidata e distrugge il contesto esattamente una volta. Gli hook legacy rimangono il fallback.
Utilizza mobile.window_focused() per mettere in pausa il lavoro visivo durante la perdita di concentrazione e mobile.memory_pressure() per svuotare le cache dopo onTrimMemory. Non considerate questi segnali come una garanzia che il processo rimarrà vivo.
Esercitazione 5: disposizione, area sicura e stoccaggio
Gli inserti sono pixel fisici: 0=left, 1=top, 2=right, 3=bottom.
use "mobile"
fn content_top() -> i64 {
mobile.window_inset(1)
}
fn text_size() -> i64 {
// scaled_density_milli is the font density multiplied by 1000.
16000 * mobile.scaled_density_milli() / 1000
}
mobile.density_dpi() e mobile.scaled_density_milli() ti consentono di adattare layout e tipografia. mobile.app_files_* e mobile.app_cache_* restituiscono viste limitate dei percorsi privati forniti da Activity; usali per l'archiviazione interna e la memorizzazione nella cache. Non è previsto l'accesso automatico alla memoria esterna. L'autorizzazione di rete dichiarata dal modello copre la sezione net corrente, ma le autorizzazioni aggiuntive rimangono di responsabilità dell'host.
Costruisci flussi
Costruzione manuale
seed --emit-shared libseed_app.so \
--target android-arm64 --runtime-profile android \
--sysroot "$ANDROID_NDK_SYSROOT" --soname libseed_app.so app.sd
seed --emit-shared libseed_app.so \
--target android-x86_64 --runtime-profile android \
--sysroot "$ANDROID_NDK_SYSROOT" --soname libseed_app.so app.sd
./seed mobile android stage my-android arm64.so x86_64.so \
seed_app com.example.seedapp
./seed mobile android package my-android
Costruzione integrata
./seed mobile android build app.sd my-android \
--ndk "$ANDROID_NDK_HOME" \
--package-name seed_app \
--application-id com.example.seedapp
build cerca l'NDK in ANDROID_NDK_HOME quando --ndk non è fornito e genera coppie shared/static per i due ABI; l'host preferisce l'oggetto condiviso confezionato e mantiene l'archivio come artefatto separato. stage continua ad accettare le librerie condivise ELF, convalida gli artefatti e rifiuta gli ID applicazione non validi. Il nome del pacchetto nativo non può contenere / o ...
Se il pacchetto Seed che contiene app.sd ha un assets/ cartella, la build integrata copia anche i suoi normali file flat nella cartella Android ospite. I nomi sono limitati a lettere e cifre ASCII, ., _, e -; le sottocartelle, i file nascosti e le collisioni con la sonda host vengono rifiutati. All'avvio, l'host legge il file generato seed-mobile-assets.list indicizza ed estrae esattamente quei file - al massimo 256 file e 64 MiB - nella root privata di sola lettura già esposta a Seed. Risorse framework o overlay elencate anche per AssetManager non inserire il pacchetto Seed. Gli stessi file manifest e immagini, font, WAV e Ogg possono quindi seguire desktop e Android senza logica di copia specifica dell'applicazione.
Le dipendenze dirette su audio-vorbis e grove-game-assets fanno sì che la build integrata includa i backend stb corrispondenti in entrambi gli ABI. Il bridge JNI fornisce il contratto audio condiviso su OpenSL ES, con flussi limitati, handle con tag di generazione, una coda PCM stereo a 48 kHz, query sui byte in sospeso, pause/resume, pulizia e chiusura esattamente una volta.
Debug, rilascio ed esecuzione
./seed mobile android package my-android
./seed mobile android package my-android --release
./seed mobile android run my-android
./seed mobile android run my-android --release
./seed mobile android run my-android --serial emulator-5554
./seed mobile android doctor --serial ZF524P7D2T
run crea pacchetti, installa, forza l'arresto dell'istanza precedente ed esegue .MainActivity tramite adb, richiedendo Status: ok. ANDROID_SERIAL può anche selezionare il dispositivo.
Per avviare l'AVD installato dal setup:
emulator -avd seed-api37 -no-snapshot
adb wait-for-device
./seed mobile android run my-android
Il nome AVD effettivo può essere richiesto con avdmanager list avd.
Matrice AVD
La matrice implementata mantiene il file system-images installato e crea uno stato AVD effimero per esecuzione. Ogni riga utilizza temporaneo ANDROID_AVD_HOME, inizializzazione senza snapshot e dati puliti; Dopo il test, chiudi ed elimina solo AVD. Le immagini SDK, NDK, Gradle e le cache di build rimangono installate. La gestione temporanea nativa e Gradle vengono eseguiti su una copia temporanea dell'host; la matrice non si riscrive seed-android.properties, jniLibs o output nel progetto originale.
Fast smoke dichiara gli AVD del telefono ARM64 nelle API 21, 29 e 37. La suite di rilascio utilizza stable API 37 con pagine tablet da 16 KB, profilo pieghevole, memoria limitata e otto cicli di vita. Non esiste un livello notturno né alcun obbligo di esecuzione x86_64; android-x86_64 rimane coperto da compile/link solo contratti.
Il runner crea l'APK una volta e lo riutilizza. Ogni riga convalida l'avvio, doctor --serial, install/cold lancio, accessibilità, base touch/key/IME, insets/density/focus, lifecycle/rotation, Logcat e arresto. La suite di rilascio ripete il ciclo di vita secondo la riga e si inserisce RUNNING_CRITICAL nello scenario con memoria limitata. Gli errori preservano la configurazione, Logcat, dumpsys, gfxinfo, meminfo, albero di accessibilità e screenshot in compiler/llvm/build/android-avd-matrix/.
make -C seed/compiler/llvm android-avd-matrix-check
make -C seed/compiler/llvm android-avd-smoke
make -C seed/compiler/llvm android-avd-release
make -C seed/compiler/llvm game-seed-garden-android-avd-check
SEED_ANDROID_AVD_API=37.0 \
SEED_ANDROID_AVD_RUNNER_POLICY=required \
make -C seed/compiler/llvm android-avd-smoke
La policy auto (impostazione predefinita) registra SKIP per strumenti o immagini mancanti; required fallisce; off disabilita l'esecuzione. --install-images, in chiamata diretta a scripts/android_avd_matrix.sh, installa le immagini selezionate. SEED_ANDROID_ADB_TIMEOUT e SEED_ANDROID_AVD_BOOT_TIMEOUT limitano le chiamate adb e boot; SEED_ANDROID_AVD_VERBOSE=true preserva l'output dettagliato dell'emulatore. I tre fumi e i quattro scenari di rilascio ARM64 passano sull'Apple M4.
Il contratto Garden utilizza la stessa infrastruttura effimera. Convalida le 64 celle semantiche in verticale e orizzontale durante otto rotazioni, movimento con animazione ridotta, pause/resume, rimozione della sessione audio durante lo smontaggio, l'avvio, frames/jank e conservazione PSS. Queste misurazioni costituiscono la linea di base dell'AVD; non sostituiscono Android LeakSanitizer o misurazioni di prestazioni, temperatura e latenza su un dispositivo fisico.
Questa matrice espande solo le prove nell'emulatore. Motorola registrata in ANDROID_TARGET_BASELINE.md rimane tutta la pretesa fisica. La politica completa e l'ordine di implementazione si trovano in roadmap-mobile.md.
Test e validazione
Convalida i contratti senza SDK completo con:
make -C seed/compiler/llvm android-target-test
make -C seed/compiler/llvm android-host-check
make -C seed/compiler/llvm android-package-check
make -C seed/compiler/llvm android-build-check
make -C seed/compiler/llvm android-run-check
make -C seed/compiler/llvm android-doctor-check
Per una convalida reale, esegui doctor, esegui build, installa su AVD o dispositivo ed esegui run. La base delle prove è in ANDROID_TARGET_BASELINE.md. doctor --serial <adb-serial> convalida anche il modello, API, ABI, patch di sicurezza e stato di autorizzazione del dispositivo selezionato.
Diagnosi del problema
-
missing Android SDK/NDK: eseguiseed mobile android setupo impostaANDROID_HOME/ANDROID_NDK_HOME. -
missing android.jar,aapt2o sysroot API 21: eseguidoctore installa il componente indicato; non utilizzare un sysroot senza directory qualificate per ABI. -
missing seed-android.properties: eseguistageobuildprimapackage/run. -
Android packaging requires Gradle: installa Gradle o inserisci un filegradleweseguibile sull'host. -
dispositivo
offlineo mancante: controllaadb devices, accetta il debug USB prompt dei tasti e utilizzare--serial. -
Mancante
Status: ok: vediadb logcat, confermare l'ID dell'applicazione e controlla se le due librerie sono state installate injniLibs. -
ABI fallimento: non mescolare
android-arm64conx86_64; la messa in scena convalida il Tipo ELF prima di copiare la libreria. -
avviso
This app isn’t 16 KB compatible: utilizzare l'attuale compiler/host; entrambi collega segmenti ELF Android con allineamento di 16.384 byte.
Limiti e prossimi passi
L'attuale ponte è una base operativa, non una promessa di compatibilità con l'insieme Android SDK. Un catalogo di widget, layout mantenuto, navigazione, un editor di testo completo, TalkBack per dispositivi fisici, plug-in stabili, un ispettore, un profiler, ricarica a caldo, un'ampia matrice di dispositivi, pubblicazione di negozi e firma di produzione rimangono sulla tabella di marcia. iOS è attivo nel simulatore tramite il compilatore, il runtime, l'host Swift e XCFramework; l'esecuzione, il provisioning, la firma e la pubblicazione dello store del dispositivo fisico rimangono aperti.
Riferimenti
- Tabella di marcia mobile
- Android versione host
- Libreria
mobile - Installazione della libreria
- JNI pubblico ABI