# Integração nativa (PlatformUtils, JNI, crossfly-lib)

> Como o código Java neutro alcança o SO — o ponto único PlatformUtils e o padrão de fallback.

Source: https://crossfly.dev/pt/docs/platforms/native-integration — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Integração nativa 🤖🍎🖥️

Como o código Java **neutro** (em `core`) alcança recursos do SO que variam por plataforma.

## `PlatformUtils` — o ponto único de abstração
`PlatformUtils.instance` é a fachada de plataforma. **Cada launcher instala sua implementação**
(o web instala `PlatformUtilsWeb`). Métodos-chave:
```java
IWebView wv = PlatformUtils.instance.createWebView();   // null onde não há webview (web)
PlatformUtils.instance.view(url);                        // abre URL externa
PlatformUtils.instance.dial(numero);                     // disca
```

## A biblioteca nativa `crossfly-lib`
Carregada no arranque por `SharedLibraryLoader.load("crossfly-lib")` dentro de `Main.create()` —
**em todos os alvos, exceto WebGL**:
```java
if (Gdx.app.getType() != Application.ApplicationType.WebGL)
   new SharedLibraryLoader().load("crossfly-lib");
```
Por isso, tudo que depende dela (ex.: `NativeImage` via JNI) **não existe no web** — lá vale a
implementação Java pura (`JavaImageOps`) ou o *stub*.

## O padrão "recurso nativo com fallback"
Sempre **cheque** antes de usar um recurso que pode não existir:
```java
if (PlatformUtils.instance.createWebView() != null) {
   WebContainer c = new WebContainer();     // Android/iOS/Desktop
   painel.add(LAY_FILL, c);
   c.show(url);
} else {
   PlatformUtils.instance.view(url);        // Web: abre externamente
}
```
O mesmo vale para retornos `null` de câmera/mapa e para `Device.platform`:
```java
if (Device.platform.isDesktop()) { /* caminho desktop */ }
```

## Escrever uma implementação nativa própria
Serviços concretos (webview, GPS, etc.) vivem **fora do `core`**, em cada launcher. Para um recurso
novo, defina a interface no `core` e implemente-a por launcher, instalando-a em `PlatformUtils`/campo
de serviço no arranque. A abstração de imagem segue esse modelo: `ImageOps` → `JavaImageOps` (JVM) vs
`NativeImage` (JNI).

## Boas práticas
- **Nunca** assuma que um recurso de dispositivo existe — cheque `!= null`/`Device.platform`.
- Coloque o código específico de SO **no launcher**, não no `core`.

## Erros comuns
- Chamar um recurso nativo sem fallback (quebra no web).
- Esperar `crossfly-lib`/JNI no web (não é carregada no WebGL).

## Veja também
- [Web (TeaVM)](/docs/platforms/web-teavm) · [WebContainer](/docs/ui/widgets/webcontainer)
