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:
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:
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:
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:
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).