Android applications avec seed
Ce guide décrit comment utiliser le courant Android seed plateforme et framework. Le support mis en œuvre combine un seed bibliothèque (mobile), un Android hôte basé sur Gradle/Kotlin/CMake, et un pont JNI qui charge le natif seed bibliothèque.
État actuel : Android est la plateforme mobile active. Le cadre fournit un Surface du canevas conservée pilotée par les commandes de frame, la saisie de base, le cycle de vie, encarts, métriques d'écran et multi-ABI emballage. Ce n'est pas encore terminé boîte à outils de widgets.
Ce qui est pris en charge
android-arm64comme exécuté mobile ABI;android-x86_64reste seulement comme cible build/link compatible ;- Android API 37, outils de ligne de commande 22.0, outils de construction 37.0.0, Gradle 9.5.0,
AGP 9.3.0 et NDK
27.2.12479018comme référence ; - shared/static seed bibliothèques chargées par un Android hôte;
seed_mobile_entryhooks à entrée unique et de cycle de vie ;- cadres avec une couleur d'arrière-plan, jusqu'à 256 rectangles, 32 éléments de texte et 128 nœuds sémantiques ;
- toucher, touches et
InputConnection.commitTextvia une file d'attente délimitée ; - encarts de fenêtre, focus, pression mémoire, densité et répertoires privés ;
- un contexte optionnel par génération
Activityet une sortie PCM stéréo via OpenSL ES avec pause/resume; - exécution en AVD et installation/launch via
adb; - development/release signature et exécution validées sur le déclaré Tranche de périphérique physique Motorola Android 15/API 35 ARM64.
Les éléments suivants ne constituent pas des revendications de support actuel : un catalogue complet de widgets, TalkBack sur appareil physique, un IME selection/composition, la mise en forme du texte, le rechargement à chaud, une large matrice de périphériques, la publication en magasin ou la préparation à la production.
Architecture
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
Le seed l'application ne remplace pas encore Activity. Le Android L'hôte reste responsable du processus, de la fenêtre, du Canvas, de JNI et de l'intégration avec le SDK. Le mobile La bibliothèque fournit les importations portables de la tranche implémentée et ne doit être utilisée qu'avec un Android cible.
Exigences
Vous devez avoir :
- macOS Apple Silicon pour la matrice ARM64 actuellement validée ;
- JDK17 ;
- NDK
clang,adb, Android CLI/sdkmanager,aapt2, Gradle et émulateur ; - un
arm64-v8aAVD ouadb-autorisé ARM64 Android appareil.
L'installateur officiel du projet utilise $HOME/Android/Sdk, ne nécessite pas sudo, et installe la ligne de base complète :
./seed mobile android setup
./seed mobile android doctor
Options utiles :
./seed mobile android setup --sdk "$HOME/Android/Sdk" --start
./seed mobile android setup --skip-avd
./seed mobile android setup --dry-run
Utiliser --api, --abi, --image-flavor, --ndk, --avd, et --device pour personnaliser l'installation. --skip-gradle laisse l'installation de Gradle à l'utilisateur. Pour utiliser un NDK autre que la ligne de base, déclarez explicitement SEED_ANDROID_NDK_REVISION et confirmer la compatibilité avec le projet.
Les diagnostics doivent montrer Android 37.0, build-tools 37.0.0, Gradle 9.5.0, platform-tools, NDK et le API 21 racines système de aarch64-linux-android et x86_64-linux-android:
./seed mobile android doctor
Tutoriel 1 : première application
Créer app.sd:
fn main() -> i64 {
0
}
pub fn seed_mobile_entry() -> i64 {
0
}
Créez un hôte en copiant le modèle versionné :
cp -R seed/compiler/llvm/mobile/android my-android
Compilez les deux ABI, préparez et générez l'APK :
./seed mobile android build app.sd my-android \
--package-name seed_app \
--application-id com.example.seedapp \
--package
La commande produit libseed_app.so et libseed_app.a pour arm64-v8a et x86_64, copie les artefacts dans my-android/app/src/main/jniLibs/, lie le seed objet partagé en tant que dépendance de pont JNI packagée et exécute assembleDebug; l'archive reste disponible séparément pour les consommateurs natifs. Le my-android/seed-android.properties Le fichier enregistre le nom natif et l'ID d'application utilisés par les commandes suivantes.
Tutoriel 2 : dessiner un écran
Importez la bibliothèque mobile Android dans votre code d'application. Un exemple complet se trouve dans compiler/llvm/tests/mobile/android_framework.sd. Le rappel de trame reçoit la largeur, la hauteur et la durée en nanosecondes :
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)
}
Les coordonnées et la taille de la police sont exprimées en millipixels. Les couleurs sont des entiers ARVB. L'hôte limite chaque image à 256 rectangles, 32 éléments de texte, 128 nœuds sémantiques et 256 octets UTF-8 par étiquette ou élément. Le texte est dessiné par le canevas Android ; la sélection des polices et la mise en forme avancée ne font pas encore partie du contrat.
Tutoriel 3 : Consommer le toucher, le clavier et IME
La bibliothèque gère une file d'attente limitée de 128 événements. Lisez les champs avant de supprimer un événement :
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 doit être appelé une fois par événement. Si les producteurs dépassent leur capacité, la file d'attente conserve les événements les plus récents. Les régions de sélection et de composition ne sont pas encore exposées.
Tutoriel 4 : Cycle de vie et ressources
Définissez uniquement les hooks nécessaires. Ils s'exécutent sur le thread Activity et ne doivent pas bloquer, conserver les objets JNI ou créer des tâches sans groupe structuré :
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 est protégé contre les exécutions répétées dans le même processus ; la recréation de Activity ne redémarre pas l'application. La destruction est annulée en attendant les travaux sur le pont ; la mort du processus est la limite finale du nettoyage.
Les applications dotées de capacités persistantes multi-images peuvent exporter seed_mobile_context_create, seed_mobile_context_on_event, seed_mobile_context_on_frame, et seed_mobile_context_destroy. L'hôte conserve au plus un contexte par génération de Activity, arrête de transférer les rappels lorsque cette génération est invalidée et détruit le contexte exactement une fois. Les hooks hérités restent la solution de repli.
Utilisez mobile.window_focused() pour suspendre le travail visuel en cas de perte de concentration et mobile.memory_pressure() pour vider les caches après onTrimMemory. Ne considérez pas ces signaux comme une garantie que le processus restera vivant.
Tutoriel 5 : aménagement, zone sécurisée et rangement
Les encarts sont des pixels physiques : 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() et mobile.scaled_density_milli() vous permettent d'adapter la mise en page et la typographie. mobile.app_files_* et mobile.app_cache_* renvoyer des vues délimitées des chemins privés fournis par Activity; utilisez-les pour le stockage interne et la mise en cache. Il n’y a pas d’accès automatique au stockage externe. L'autorisation réseau déclarée par le modèle couvre l'actuel net slice, mais les autorisations supplémentaires restent sous la responsabilité de l'hôte.
Créer des flux
Construction manuelle
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
Construction intégrée
./seed mobile android build app.sd my-android \
--ndk "$ANDROID_NDK_HOME" \
--package-name seed_app \
--application-id com.example.seedapp
build recherche le NDK dans ANDROID_NDK_HOME lorsque --ndk n'est pas fourni et génère des paires shared/static pour les deux ABI ; l'hôte préfère l'objet partagé packagé et conserve l'archive en tant qu'artefact distinct. stage continue d'accepter les bibliothèques partagées ELF, valide les artefacts et rejette les ID d'application non valides. Le nom du package natif ne peut pas contenir / ou ...
Si le package Seed qui contient app.sd a un assets/ dossier, la version intégrée copie également ses fichiers plats réguliers dans le dossier Android hôte. Les noms sont limités aux lettres et chiffres ASCII, ., _, et -; les sous-dossiers, les fichiers cachés et les collisions avec la sonde hôte sont rejetés. Au démarrage, l'hôte lit le généré seed-mobile-assets.list indexe et extrait exactement ces fichiers (au maximum 256 fichiers et 64 Mo) vers la racine privée en lecture seule déjà exposée à Seed. Actifs de framework ou de superposition également répertoriés par AssetManager n’entrez pas dans le package Seed. Les mêmes ressources manifeste et image, police, WAV et Ogg peuvent donc suivre le bureau et Android sans logique de copie spécifique à l'application.
Les dépendances directes sur audio-vorbis et grove-game-assets font que la version intégrée inclut les backends stb correspondants dans les deux ABI. Le pont JNI fournit le contrat audio partagé sur OpenSL ES, avec des flux limités, des poignées étiquetées par génération, une file d'attente PCM stéréo de 48 kHz, des requêtes d'octets en attente, pause/resume, un nettoyage et une fermeture exacte une fois.
Débogage, publication et exécution
./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 emballe, installe, force l'arrêt de l'instance précédente et exécute .MainActivity via adb, nécessitant Status: ok. ANDROID_SERIAL peut également sélectionner l'appareil.
Pour démarrer l'AVD installé par le programme d'installation :
emulator -avd seed-api37 -no-snapshot
adb wait-for-device
./seed mobile android run my-android
Le nom AVD réel peut être interrogé avec avdmanager list avd.
Matrice AVD
La matrice implémentée conserve le system-images installé et crée un état AVD éphémère par exécution. Chaque ligne utilise du temporaire ANDROID_AVD_HOME, initialisation sans instantané et données propres ; Après le test, fermez et supprimez uniquement l'AVD. Les images SDK, NDK, Gradle et les caches de build restent installés. La mise en scène native et Gradle s'exécutent sur une copie temporaire de l'hôte ; la matrice ne se réécrit pas seed-android.properties, jniLibs ou les sorties dans le projet original.
Fast Smoke déclare les AVD des téléphones ARM64 dans les API 21, 29 et 37. La suite de versions utilise des versions stables. API 37 avec 16 Ko de pages pour tablette, profil pliable, mémoire limitée et huit cycles de vie. Il n'y a pas de niveau nocturne et aucune obligation d'exécuter x86_64; android-x86_64 reste couvert par compile/link contrats uniquement.
Le coureur crée l’APK une fois et le réutilise. Chaque ligne valide le démarrage, doctor --serial, install/cold lancement, accessibilité, basique touch/key/IME, insets/density/focus, lifecycle/rotation, Logcat et arrêt. La suite de versions répète le cycle de vie selon la ligne et injecte RUNNING_CRITICAL dans le scénario de mémoire limitée. Les échecs préservent la configuration, Logcat, dumpsys, gfxinfo, meminfo, arborescence d'accessibilité et capture d'écran dans 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 stratégie auto (par défaut) enregistre SKIP pour les outils ou images manquants ; required échoue ; off désactive l'exécution. --install-images, en appel direct à scripts/android_avd_matrix.sh, installe les images sélectionnées. SEED_ANDROID_ADB_TIMEOUT et SEED_ANDROID_AVD_BOOT_TIMEOUT limitent les appels adb et boot ; SEED_ANDROID_AVD_VERBOSE=true préserve la sortie détaillée de l’émulateur. Les trois scénarios de sortie et les quatre scénarios de version ARM64 sont transmis à l'Apple M4.
Le contrat Garden utilise la même infrastructure éphémère. Il valide les 64 cellules sémantiques en portrait et paysage lors de huit rotations, mouvement avec animation réduite, pause/resume, suppression de la session audio lors du démontage, du démarrage, frames/jank et la rétention du PSS. Ces mesures constituent la référence AVD ; ils ne remplacent pas Android LeakSanitizer ou mesures de performances, thermiques et de latence sur un appareil physique.
Cette matrice élargit uniquement les preuves dans l'émulateur. Motorola enregistré sous ANDROID_TARGET_BASELINE.md reste toute réclamation physique. La politique complète et l’ordre de mise en œuvre se trouvent dans roadmap-mobile.md.
Tests et validation
Validez les contrats sans SDK complet avec :
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
Pour une validation réelle, exécutez doctor, effectuez build, installez sur AVD ou un périphérique, puis exécutez run. La base de données probantes se trouve dans ANDROID_TARGET_BASELINE.md. doctor --serial <adb-serial> valide également le modèle, API, ABI, le correctif de sécurité et l'état d'autorisation du périphérique sélectionné.
Diagnostic du problème
-
missing Android SDK/NDK: courirseed mobile android setupou définirANDROID_HOME/ANDROID_NDK_HOME. -
missing android.jar,aapt2ou sysroot API 21 : exécutezdoctoret installez le composant indiqué ; n'utilisez pas de racine système sans répertoires qualifiés ABI. -
missing seed-android.properties: Courirstageoubuildavantpackage/run. -
Android packaging requires Gradle: installez Gradle ou mettez ungradlewexécutable sur l'hôte. -
périphérique
offlineou manquant : vérifiezadb devices, acceptez le débogage USB invite de touche et utilisez--serial. -
Manquant
Status: ok: voiradb logcat, confirmez l'ID de l'application et vérifiez si les deux bibliothèques ont été installées dansjniLibs. -
ABI échec : ne pas mélanger
android-arm64avecx86_64; la mise en scène valide la Tapez ELF avant de copier la bibliothèque. -
avertissement
This app isn’t 16 KB compatible: utiliser le courant compiler/host; les deux reliez les segments ELF Android avec un alignement de 16 384 octets.
Limites et prochaines étapes
Le pont actuel est une base opérationnelle et non une promesse de compatibilité avec l'ensemble Android SDK. Un catalogue de widgets, une mise en page conservée, une navigation, un éditeur de texte complet, TalkBack sur appareil physique, des plugins stables, un inspecteur, un profileur, un rechargement à chaud, une large matrice d'appareils, la publication en magasin et la signature de production restent sur la feuille de route. iOS est actif dans le simulateur via le compilateur, le runtime, l'hôte Swift et XCFramework ; L'exécution, le provisionnement, la signature et la publication des périphériques physiques restent ouverts.
Références
- Feuille de route mobile
- Android hôte versionné
- Bibliothèque
mobile - Installation de la bibliothèque
- Public JNI ABI