Android Guia de Plataforma

O backend Android oferece um pipeline completo que transforma um projeto do IDE em um APK assinado rodando em um emulador ou dispositivo Android real, com controles nativos android.widget.*. O mesmo codigo Harbour que roda nos desktops Windows, macOS e Linux agora tambem compila para Android — sem WebView, sem UI skinned, sem dependencia de runtime.

Estatisticas do Backend
StatusIteracao 1 — disponivel agora
LinguagemC (JNI) + Java
API Nativaandroid.widget.* via JNI
SDK MinimoAPI 24 (Android 7.0 Nougat)
SDK AlvoAPI 34 (Android 14)
ABIarm64-v8a (ARM 64-bit)
ToolchainNDK r26d · SDK 34 · JDK 17
Validado emEmulador Pixel 5 / Android 14
⚠️ Em desenvolvimento. A iteracao 1 implementa UI_FormNew, UI_LabelNew, UI_ButtonNew, UI_EditNew, UI_SetText, UI_GetText e UI_OnClick. Mais controles (ComboBox, ListView, CheckBox, RadioButton, DatePicker…) serao adicionados nas proximas iteracoes. Veja o Roadmap abaixo.

Visao Geral da Arquitetura

Android e o 4o backend GUI nativo do HarbourBuilder. O mesmo classes.prg que todas as outras plataformas usam despacha para android_core.c em vez da bridge Win32 / Cocoa / GTK3, e as chamadas JNI se transformam em controles Android reais adicionados a um FrameLayout dentro de MainActivity.

graph TB A["Harbour .prg
DEFINE FORM ... BUTTON ..."] --> B["classes.prg
UI_FormNew, UI_ButtonNew, ..."] B --> C["android_core.c
HB_FUNC + bridge JNI"] C -->|JNI CallVoidMethod| D["MainActivity.java
Host FrameLayout"] D --> E["android.widget.TextView"] D --> F["android.widget.Button"] D --> G["android.widget.EditText"] F -->|onClick| H["nativeOnClick(id)"] H -->|hb_evalBlock0| B style A fill:#8b5cf6,stroke:#7c3aed,color:#fff style B fill:#f59e0b,stroke:#d97706,color:#0d1117 style C fill:#34c759,stroke:#28a745,color:#0d1117 style D fill:#34c759,stroke:#28a745,color:#0d1117 style E fill:#3ddc84,stroke:#1a8d4d,color:#0d1117 style F fill:#3ddc84,stroke:#1a8d4d,color:#0d1117 style G fill:#3ddc84,stroke:#1a8d4d,color:#0d1117 style H fill:#34c759,stroke:#28a745,color:#0d1117

Cada backend do HarbourBuilder implementa a mesma familia de HB_FUNCs UI_*; o do Android esta em source/backends/android/android_core.c e espelha, HB_FUNC por HB_FUNC, a bridge Win32 (source/cpp/hbbridge.cpp) e a bridge Cocoa (source/backends/cocoa/cocoa_core.m).

Pipeline de Compilacao

O item de menu Run → Run on Android… aciona um pipeline de 8 etapas que produz um APK assinado pronto para instalar. O mesmo pipeline esta disponivel como script independente em source/backends/android/build-apk-gui.sh.

graph LR A[".prg fonte"] --> B["1. harbour.exe
prg → .c"] B --> C["2. clang
C → .o"] C --> D["3. clang --shared
libapp.so"] D --> E["4. aapt2 compile
recursos"] E --> F["5. aapt2 link
base.apk"] F --> G["6. javac
MainActivity.class"] G --> H["7. d8
classes.dex"] H --> I["8. zipalign + apksigner
APK assinado"] style I fill:#34c759,stroke:#28a745,color:#0d1117
  1. harbour.exe — compilador Harbour host transpila .prg para C portavel.
  2. clang (NDK) — cross-compila C para objetos aarch64-linux-android24.
  3. clang --shared — linka libapp.so com o conjunto completo de bibliotecas estaticas harbour/core (hbvm, hbrtl, hblang, hbcpage, hbrdd, hbmacro, hbpp, hbcommon, hbpcre, hbzlib, hbnulrdd, hbdebug, hbcplr, rddntx/cdx/fpt/nsx, gtstd/trm/cgi/pca, hbsix, hbhsx).
  4. aapt2 compile — compila recursos Android (res/).
  5. aapt2 link — linka recursos + manifest em base.apk; gera R.java.
  6. javac — compila MainActivity.java contra o Android SDK.
  7. d8 — dex-compila arquivos .class para classes.dex.
  8. zipalign + apksigner — alinha e assina o APK com uma keystore de debug.

API UI_* no Android

A superficie chamavel pelo Harbour exposta pelo backend Android. Todas as coordenadas estao em pixels do designer de formularios, identicas ao Win32/Cocoa/GTK3 — veja tratamento de densidade.

HB_FUNCAssinaturaMapeia para
UI_FormNew(cTitle, nW, nH) → hFormMainActivity.setTitle() — a Activity e o formulario
UI_LabelNew(hForm, cText, x, y, w, h) → hCtrlandroid.widget.TextView
UI_ButtonNew(hForm, cText, x, y, w, h) → hCtrlandroid.widget.Button
UI_EditNew(hForm, cText, x, y, w, h) → hCtrlandroid.widget.EditText
UI_SetText(hCtrl, cText)TextView.setText()
UI_GetText(hCtrl) → cTextTextView.getText()
UI_OnClick(hCtrl, bBlock)armazena o codeblock para despacho via nativeOnClick
UI_FormRun(hForm)no-op (a Activity Android possui o loop de eventos)

Bridge JNI

Cada HB_FUNC UI_* obtem o JNIEnv da thread chamadora e invoca um id de metodo em cache na referencia global da MainActivity. O lado Java executa a criacao do widget na thread de UI com runOnUiThread. Cliques viajam na direcao oposta: Button.setOnClickListener → nativeOnClick(controlId) → hb_evalBlock0.

// android_core.c — despacho UI_ButtonNew
HB_FUNC( UI_BUTTONNEW )
{
    int id = create_widget( m_createButton,
                             HB_ISCHAR(2) ? hb_parc(2) : "",
                             hb_parni(3), hb_parni(4),
                             hb_parni(5), hb_parni(6) );
    hb_retni( id );
}

// Java chamado de volta pelo nativo:
public void createButton( final int id, final String text,
                          final int x, final int y, final int w, final int h ) {
    runOnUiThread( new Runnable() { public void run() {
        Button b = new Button( MainActivity.this );
        b.setText( text );
        b.setOnClickListener( v -> nativeOnClick( id ) );
        root.addView( b, lp( x, y, w, h ) );
        ctrls.put( id, b );
    }});
}

Handles de controles sao inteiros pequenos (1..255) retornados por cada UI_*New. O lado Java indexa um HashMap<Integer, View>; o lado C mantem um array paralelo PHB_ITEM g_click_handlers[256] com os codeblocks Harbour anexados via UI_OnClick.

Coordenadas com Consciencia de Densidade

Coordenadas do designer de formularios sao 1:1 com pixels de desktop Windows. No Android os mesmos valores de pixel escalam com DisplayMetrics.density para que um botao de 100px seja consistente em telas mdpi (×1.0), hdpi (×1.5), xhdpi (×2.0), xxhdpi (×3.0) e xxxhdpi (×4.0).

// MainActivity.java — multiplicador de densidade
private int dp( int formPx ) { return Math.round( formPx * density ); }

private FrameLayout.LayoutParams lp( int x, int y, int w, int h ) {
    FrameLayout.LayoutParams p = new FrameLayout.LayoutParams( dp(w), dp(h) );
    p.leftMargin = dp(x);
    p.topMargin  = dp(y);
    return p;
}

Loop de Eventos (invertido)

No Win32, Cocoa e GTK a chamada Harbour oForm:Run() bloqueia em uma bomba de mensagens. No Android o SO possui o loop de eventos: UI_FormRun() e um no-op. O onCreate() da Activity chama nativeInit(), que inicia a VM Harbour e invoca Main()Main() cria os widgets via UI_*New e retorna. A partir de entao o ciclo de vida da Activity comanda tudo; interacoes do usuario disparam nativeOnClick, que despacha o codeblock armazenado.

Executando pelo IDE

No Windows o IDE adiciona o item de menu Run → Run on Android…. Ao clicar:

  1. Salva o projeto ativo (SaveActiveFormCode).
  2. Escreve o conteudo de Project1.prg no diretorio de build Android.
  3. Abre um dialogo de progresso e invoca build-apk.sh via Git Bash.
  4. Em caso de falha: mostra o build-apk.log completo em um dialogo de erro.
  5. Em caso de sucesso: executa run-on-emulator.sh em background — inicializa o AVD se necessario, instala o APK, lanca a activity, e exibe o logcat em um arquivo de log.
// hbbuilder_win.prg — conexao do menu
DEFINE POPUP oRun PROMPT "&Run" OF oIDE
   MENUITEM "&Run"              OF oRun ACTION TBRun()
   MENUITEM "&Debug"            OF oRun ACTION TBDebugRun()
   MENUSEPARATOR OF oRun
   MENUITEM "Run on &Android..." OF oRun ACTION TBRunAndroid()

Requisitos do Toolchain

O target Android depende de quatro toolchains externos. O Assistente de Configuracao (Run → Android Setup Wizard…) baixa e instala automaticamente em uma janela de terminal dedicada, entao em uma maquina nova basta clicar e esperar. Os caminhos abaixo sao os que o assistente (e os scripts de build) utilizam.

ComponenteVersaoCaminho padrao (Windows)
Android NDKr26dC:\Android\android-ndk-r26d\
Android SDKplatform 34 · build-tools 34.0.0C:\Android\Sdk\
JDK17 (Temurin, portavel)C:\JDK17\jdk-17.0.13+11\
Harbour Host3.2.0devC:\harbour\bin\win\bcc\harbour.exe
Git Bashqualquer versao recenteC:\Program Files\Git\bin\bash.exe
AVDPixel 5 · android-34 · google_apis · x86_64nome HarbourBuilderAVD

O footprint total do toolchain e ≈4 GB. As instalacoes sao autonomas — sem entradas no registro, sem alteracoes no PATH: os scripts de build exportam PATH internamente.

Assistente de Configuracao

O menu Run → Android Setup Wizard… abre um dialogo que relata cada componente do toolchain como OK ou FALTANDO. Se algo estiver faltando, um unico Sim lanca source/backends/android/setup-android-toolchain.sh em uma nova janela de terminal. O script e idempotente — detecta o que ja esta instalado e baixa apenas o que falta:

ComponenteTamanhoFonte
JDK 17 Temurin~175 MBAdoptium GitHub Releases
Android NDK r26d~1.5 GBdl.google.com
SDK cmdline-tools~100 MBdl.google.com
platforms;android-34, build-tools;34.0.0, platform-tools, emulator, system-image x86_64 ~1.2 GBvia sdkmanager
AVD HarbourBuilderAVDvia avdmanager
Bibliotecas Harbour-para-Android3.6 MBreleases/harbour-android-arm64-v8a.zip (incluido no repo)

O script redireciona yes para sdkmanager --licenses para que a instalacao nao seja interrompida, e aplica automaticamente o ajuste de ar/ranlib/strip do NDK que os mk files do Harbour exigem. Total de ~2.8 GB de download em uma maquina vazia. Git Bash e o unico pre-requisito que o assistente nao pode instalar para voce.

Ola Android — exemplo completo

O arquivo source/backends/android/hello_gui.prg usa a API UI_* do backend Android diretamente:

PROCEDURE Main()

   LOCAL hForm, hLabel, hEdit, hBtn

   hForm  := UI_FormNew( "Ola Android", 400, 600 )
   hLabel := UI_LabelNew(  hForm, "Digite seu nome:", 20, 20,  300, 30 )
   hEdit  := UI_EditNew(   hForm, "",                 20, 60,  300, 50 )
   hBtn   := UI_ButtonNew( hForm, "Saudar",           20, 130, 300, 50 )

   UI_OnClick( hBtn, ;
      {|| UI_SetText( hLabel, "Ola, " + UI_GetText( hEdit ) + " !" ) } )

   UI_FormRun( hForm )   // no-op no Android; a Activity possui o loop

RETURN

Compilar e implantar:

# compilar o APK
bash source/backends/android/build-apk-gui.sh

# instalar + lancar no emulador
adb install -r C:/HarbourAndroid/apk-gui/harbour-gui.apk
adb shell am start -n com.harbour.builder/.MainActivity

Limitacoes Conhecidas

Roadmap

IteracaoEntregaveis
1 ✅Pipeline APK, bridge JNI, Form/Label/Button/Edit, escalonamento de densidade, despacho de click, validado no emulador
1b ✅Designer de formularios do IDE → gerador de codigo Android (controles visuais emitem chamadas UI_*), traducao de handlers METHOD
1c ✅Cores de form/controles + fontes transportadas (UI_SetFormColor, UI_SetCtrlColor, UI_SetCtrlFont)
6 ✅Assistente de Configuracao — Run → Android Setup Wizard… baixa e instala JDK/NDK/SDK/AVD e extrai as bibliotecas Harbour incluidas
2CheckBox, RadioButton, ComboBox (Spinner), ListView, DatePicker, TimePicker, ProgressBar, Slider (SeekBar)
3Menu (ActionBar), Dialog (AlertDialog), Toast, paridade com MessageBox
4Renderizacao de Image/Bitmap, empacotamento de recursos, icones por densidade
5Painel adb logcat embutido no IDE + stream de build em tempo real + seletor de dispositivo (AVD / USB / Wi-Fi ADB)
6bPorta do Assistente de Configuracao para hosts macOS e Linux
7Gerenciador de keystore de release + exportacao AAB + assistente de upload ao Play Console
8Controles mobile: TSwitch, TSegmentedControl, TFloatingActionButton, TSwipeView, TQRScanner, TCamera, TMapView

Arquivos Fonte

ArquivoProposito
source/backends/android/android_core.cBridge JNI e HB_FUNCs UI_*
source/backends/android/java/com/harbour/builder/MainActivity.javahost FrameLayout programatico, despacho de click
source/backends/android/AndroidManifest.xmlmetadados do pacote, SDK min/target
source/backends/android/res/values/strings.xmlbundle de recursos minimo
source/backends/android/build-apk-gui.shpipeline de 8 etapas de build + assinatura
source/backends/android/hello_gui.prgPRG de demo provando o pipeline ponta-a-ponta

Nesta Pagina

Visao Geral da Arquitetura Pipeline de Compilacao API UI_* no Android Bridge JNI Coordenadas com Densidade Loop de Eventos (invertido) Executando pelo IDE Requisitos do Toolchain Ola Android — exemplo Limitacoes Conhecidas Roadmap Arquivos Fonte