Android aplicações com seed
<!-- verified-against: seed-llvm; examples: docs-examples-test -->
Este guia descreve como usar o atual Android seed plataforma e estrutura. O apoio implementado combina uma seed biblioteca (mobile), um Android anfitrião baseado em Gradle/Kotlin/CMake e uma ponte JNI que carrega o nativo seed biblioteca.
Estado atual: Android é a plataforma móvel ativa. O quadro fornece uma Superfície do Canvas retida acionada por comandos de quadro, entrada básica, ciclo de vida, inserções, métricas de tela e multi-ABI embalagem. Ainda não é um completo kit de ferramentas de widgets.
O que é suportado
android-arm64como executado móvel ABI;android-x86_64permanece apenas como alvo build/link compatível;- Android API 37, ferramentas de linha de comando 22.0, ferramentas de construção 37.0.0, Gradle 9.5.0,
AGP 9.3.0 e NDK
27.2.12479018como linha de base; - shared/static seed bibliotecas carregadas por um Android anfitrião;
seed_mobile_entryganchos de entrada única e de ciclo de vida;- quadros com cor de fundo, até 256 retângulos, 32 itens de texto e 128 nós semânticos;
- toque, teclas e
InputConnection.commitTextpor meio de uma fila limitada; - inserções de janela, foco, pressão de memória, densidade e diretórios privados;
- um contexto opcional por geração
Activitye saída PCM estéreo via OpenSL ES com pause/resume; - execução em AVD e installation/launch via
adb; - development/release assinatura e execução validadas no declarado Fatia de dispositivo físico Motorola Android 15/API 35 ARM64.
O que se segue não são reivindicações de suporte atual: um catálogo completo de widgets, TalkBack para dispositivo físico, suporte completo IME selection/composition, modelagem de texto, recarga a quente, ampla matriz de dispositivos, publicação na loja ou prontidão para produção.
Arquitetura
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
O seed o aplicativo ainda não substitui Activity. O Android host continua responsável pelo processo, janela, Canvas, JNI e integração com o SDK. O mobile biblioteca fornece as importações portáteis da fatia implementada e só deve ser usada com um Android alvo.
Requisitos
Você deve ter:
- macOS Apple Silicon para a matriz ARM64 atualmente validada;
- JDK 17;
- NDKs
clang,adb, Android CLI/sdkmanager,aapt2, Gradle e emulador; - um
arm64-v8aAVD ouadb- ARM64 autorizado Android dispositivo.
O instalador oficial do projeto usa $HOME/Android/Sdk, não requer sudoe instala a linha de base completa:
./seed mobile android setup
./seed mobile android doctor
Opções úteis:
./seed mobile android setup --sdk "$HOME/Android/Sdk" --start
./seed mobile android setup --skip-avd
./seed mobile android setup --dry-run
Usar --api, --abi, --image-flavor, --ndk, --avde --device para personalizar a instalação. --skip-gradle deixa a instalação do Gradle por conta do usuário. Para usar um NDK diferente da linha de base, declare explicitamente SEED_ANDROID_NDK_REVISION e confirmar a compatibilidade com o projeto.
O diagnóstico deve mostrar Android 37.0, build-tools 37.0.0, Gradle 9.5.0, platform-tools, NDK e os sysroots API 21 de aarch64-linux-android e x86_64-linux-android:
./seed mobile android doctor
Tutorial 1: primeira aplicação
Crie app.sd:
fn main() -> i64 {
0
}
pub fn seed_mobile_entry() -> i64 {
0
}
Crie um host copiando o modelo com versão:
cp -R seed/compiler/llvm/mobile/android my-android
Compile ambas as ABIs, prepare e gere o APK:
./seed mobile android build app.sd my-android \
--package-name seed_app \
--application-id com.example.seedapp \
--package
O comando produz libseed_app.so e libseed_app.a para arm64-v8a e x86_64, copia os artefatos para my-android/app/src/main/jniLibs/, vincula o objeto compartilhado seed como uma dependência de ponte JNI empacotada e executa assembleDebug; o arquivo permanece disponível separadamente para consumidores nativos. O arquivo my-android/seed-android.properties registra o nome nativo e o ID do aplicativo usado pelos comandos subsequentes.
Tutorial 2: desenhe uma tela
Importe a biblioteca mobile Android para o código do seu aplicativo. Um exemplo completo está em compiler/llvm/tests/mobile/android_framework.sd. O retorno de chamada do quadro recebe largura, altura e tempo em nanossegundos:
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);
}
As coordenadas e o tamanho da fonte são expressos em milipixels. As cores são inteiros ARGB. O host limita cada quadro a 256 retângulos, 32 itens de texto, 128 nós semânticos e 256 UTF-8 bytes por rótulo ou item. O texto é desenhado pelo Android Lona; seleção de fontes e modelagem avançada ainda não fazem parte do contrato.
Tutorial 3: Consumir Touch, Teclado e IME
A biblioteca mantém uma fila limitada de 128 eventos. Leia os campos antes de remover um 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 ser chamado uma vez por evento. Se os produtores excederem a capacidade, a fila retém os eventos mais recentes. A região de seleção e composição ainda não está exposta.
Tutorial 4: Ciclo de vida e recursos
Defina apenas os ganchos necessários. Eles são executados no encadeamento Activity e não devem bloquear, reter objetos JNI ou criar tarefas sem um grupo estruturado:
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á protegido contra execução repetida no mesmo processo; recriar Activity não reinicia o aplicativo. Destruição cancela obras pendentes na ponte; a morte do processo é o limite final da limpeza.
Aplicativos com recursos persistentes de cross-frame podem exportar seed_mobile_context_create, seed_mobile_context_on_event, seed_mobile_context_on_framee seed_mobile_context_destroy. O host mantém no máximo um contexto por geração de Activity, interrompe o encaminhamento de retornos de chamada quando esta geração é invalidada e destrói o contexto exatamente uma vez. Os ganchos legados continuam sendo a alternativa.
Use mobile.window_focused() para pausar o trabalho visual durante a perda de foco e mobile.memory_pressure() para liberar caches após onTrimMemory. Não trate esses sinais como uma garantia de que o processo permanecerá ativo.
Tutorial 5: layout, área segura e armazenamento
As inserções são pixels físicos: 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() permitem adaptar layout e tipografia. mobile.app_files_* e mobile.app_cache_* retornam visualizações limitadas dos caminhos privados fornecidos por Activity; use-os para armazenamento interno e cache. Não há acesso automático ao armazenamento externo. A permissão de rede declarada pelo modelo cobre a fatia net atual, mas as permissões adicionais permanecem de responsabilidade do host.
Construir fluxos
Construção manual
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
Construção integrada
./seed mobile android build app.sd my-android \
--ndk "$ANDROID_NDK_HOME" \
--package-name seed_app \
--application-id com.example.seedapp
build procura o NDK em ANDROID_NDK_HOME quando --ndk não é fornecido e gera pares shared/static para as duas ABIs; o host prefere o objeto compartilhado empacotado e mantém o arquivo como um artefato separado. stage continua a aceitar bibliotecas compartilhadas ELF, valida artefatos e rejeita IDs de aplicativos inválidos. O nome do pacote nativo não pode conter / ou ...
Se o pacote Seed que contém app.sd tem um assets/ pasta, a compilação integrada também copia seus arquivos simples regulares para a pasta Android anfitrião. Os nomes são limitados a letras e dígitos ASCII, ., _e -; subpastas, arquivos ocultos e colisões com a investigação do host são rejeitados. Na inicialização, o host lê o gerado seed-mobile-assets.list indexa e extrai exatamente esses arquivos — no máximo 256 arquivos e 64 MiB — para a raiz privada somente leitura já exposta ao Seed. Ativos de estrutura ou sobreposição também listados por AssetManager não entre no pacote Seed. O mesmo manifesto e recursos de imagem, fonte, WAV e Ogg podem, portanto, seguir desktop e Android sem lógica de cópia específica do aplicativo.
Dependências diretas em audio-vorbis e grove-game-assets fazem com que a construção integrada inclua os back-ends stb correspondentes em ambas as ABIs. A ponte JNI fornece o contrato de áudio compartilhado sobre OpenSL ES, com fluxos limitados, identificadores marcados por geração, uma fila PCM estéreo de 48 kHz, consultas de bytes pendentes, pause/resume, limpeza e fechamento exatamente uma vez.
Depurar, liberar e executar
./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 empacota, instala, força a parada da instância anterior e executa .MainActivity via adb, exigindo Status: ok. ANDROID_SERIAL também pode selecionar o dispositivo.
Para iniciar o AVD instalado pela configuração:
emulator -avd seed-api37 -no-snapshot
adb wait-for-device
./seed mobile android run my-android
O nome real do AVD pode ser consultado com avdmanager list avd.
Matriz AVD
A matriz implementada mantém o system-images instalado e cria um estado AVD efêmero por execução. Cada linha usa temporário ANDROID_AVD_HOME, inicialização sem instantâneo e dados limpos; Após o teste, feche e exclua apenas o AVD. Imagens SDK, NDK, Gradle e caches de build permanecem instalados. O teste nativo e o Gradle são executados em uma cópia temporária do host; a matriz não reescreve seed-android.properties, jniLibs ou resultados no projeto original.
Fast smoke declara AVDs de telefone ARM64 nas APIs 21, 29 e 37. O conjunto de lançamento usa stable API 37 com páginas de tablet de 16 KB, perfil dobrável, memória limitada e oito ciclos de vida. Não há nível noturno e nenhum requisito para execução x86_64; android-x86_64 permanece coberto por compile/link apenas contratos.
O executor cria o APK uma vez e o reutiliza. Cada linha valida a inicialização, doctor --serial, install/cold lançamento, acessibilidade, básico touch/key/IME, insets/density/focus, lifecycle/rotation, Logcat e desligamento. O conjunto de lançamento repete o ciclo de vida conforme a linha e injeta RUNNING_CRITICAL no cenário de memória limitada. As falhas preservam a configuração, Logcat, dumpsys, gfxinfo, meminfo, árvore de acessibilidade e captura de tela em 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
A política auto (padrão) registra SKIP para ferramentas ou imagens ausentes; required falha; off desativa a execução. --install-images, em chamada direta para scripts/android_avd_matrix.sh, instala imagens selecionadas. SEED_ANDROID_ADB_TIMEOUT e SEED_ANDROID_AVD_BOOT_TIMEOUT limitam chamadas adb e boot; SEED_ANDROID_AVD_VERBOSE=true preserva a saída detalhada do emulador. Os três cenários de lançamento do Smoke e os quatro ARM64 passam no Apple M4.
O contrato Garden utiliza a mesma infraestrutura efêmera. Valida as 64 células semânticas em retrato e paisagem durante oito rotações, movimento com animação reduzida, pause/resume, remoção da sessão de áudio durante a desmontagem, inicialização, frames/jank e retenção de PSS. Estas medições são a linha de base do AVD; eles não substituem Android LeakSanitizer ou medições de desempenho, térmicas e latência em um dispositivo físico.
Esta matriz apenas expande a evidência no emulador. A Motorola registrada em ANDROID_TARGET_BASELINE.md permanece apenas com reivindicação física. A política completa e a ordem de implementação estão em roadmap-mobile.md.
Teste e validação
Valide contratos sem SDK completo com:
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
Para validação real, execute doctor, faça build, instale no AVD ou dispositivo e execute run. A linha de base da evidência está em ANDROID_TARGET_BASELINE.md. doctor --serial <adb-serial> também valida o modelo, API, ABI, patch de segurança e estado de autorização do dispositivo selecionado.
Diagnóstico de problemas
-
missing Android SDK/NDK: executeseed mobile android setupou definaANDROID_HOME/ANDROID_NDK_HOME. -
missing android.jar,aapt2ou sysroot API 21: executedoctore instale o componente indicado; não use um sysroot sem diretórios qualificados para ABI. -
missing seed-android.properties: Executestageoubuildantespackage/run. -
Android packaging requires Gradle: instale o Gradle ou coloque umgradlewexecutável no host. -
dispositivo
offlineou ausente: verifiqueadb devices, aceite a depuração USB prompt de tecla e use--serial. -
Desaparecido
Status: ok: vejaadb logcat, confirme o ID do aplicativo e verifique se as duas bibliotecas foram instaladas emjniLibs. -
ABI falha: não misture
android-arm64comx86_64; a preparação valida o Digite ELF antes de copiar a biblioteca. -
aviso
This app isn’t 16 KB compatible: use a corrente compiler/host; ambos vincular segmentos ELF Android com alinhamento de 16.384 bytes.
Limites e próximos passos
A ponte actual é uma base operacional, não uma promessa de compatibilidade com todo o Android SDK. Um catálogo de widgets, layout retido, navegação, um editor de texto completo, TalkBack para dispositivos físicos, plug-ins estáveis, um inspetor, um criador de perfil, recarga a quente, uma ampla matriz de dispositivos, publicação na loja e assinatura de produção permanecem no roteiro. iOS está ativo no simulador por meio do compilador, tempo de execução, host Swift e XCFramework; a execução de dispositivos físicos, o provisionamento, a assinatura e a publicação na loja permanecem abertos.
Referências
- Roteiro móvel
- Android host versionado
- Biblioteca
mobile - Instalação da biblioteca
- JNI público ABI