Android map view
Add SqsMapView directly to an Android layout. It combines the existing map host and touch adapter, displays native RGBA frames, and forwards viewport density and input to the shared map core. Java requires API24+. Package matching-ABI libsqs_map.so and libsqsmap_mobile.so. Scripts retain import {map} from 'sqsmap'.
SqsMapView mapView = new SqsMapView(this);
mapView.setListener(new SqsMapView.Listener() {
@Override public void onReady(SqsMapView view, NativeMapHost host) {
host.runScript("import {map} from 'sqsmap';"
+ "map.jumpTo({center:[0,0],zoom:3});"
+ "map.addSource('demo',{type:'geojson',data:{type:'Feature',"
+ "properties:{},geometry:{type:'Polygon',coordinates:"
+ "[[[-4,-4],[4,-4],[4,4],[-4,4],[-4,-4]]]}}});"
+ "map.addLayer({id:'demo-fill',type:'fill',source:'demo',"
+ "paint:{'fill-color':'#ef4444'}});export default {};")
.whenComplete((state, error) -> view.post(() -> {
if (!view.isCurrent(host)) return;
if (error != null) android.util.Log.e("SqsMap", "Initialization failed", error);
}));
}
@Override public void onError(SqsMapView view, Throwable error) {
android.util.Log.e("SqsMap", "Map error", error);
}
});
setContentView(mapView);
Construction, listener configuration, state queries, lifecycle calls, and callbacks run on the main thread. runScript(module) is a convenience method for a ready view; it returns a failed future before readiness. Configure setTransportFactory() before opening; each map generation creates a separate Transport closed with its host. An attached, laid-out, unpaused view opens a map and calls onReady with that generation's NativeMapHost. getHost() returns null before readiness; isReady() means the host opened, while onScriptState reports script initialization. Never block the UI or owner thread on their own futures. Check isCurrent(host) before using asynchronous results.
Connect Activity/Fragment lifecycle to pause(), resume(), and final destroy() / destroyAsync(). Pausing or detaching immediately invalidates the generation, detaches touch input, clears pending frames, and closes the entire map host, cancelling HTTP/WS and script tasks. Resume or reattachment waits for the previous host to close before opening a new map and calling onReady again. Camera, layers, images, and scripts are not automatically retained; initialize them in every onReady. Final destruction prevents further resume. Reattachment never reuses an old map handle.
The whole View is the shared drawing and input rectangle. Logical dimensions round the physical View size divided by display density; actual native frames stretch to that rectangle. Touch coordinates use the same rectangle, with pan, pinch zoom, rotation, pitch, and shared taps controlled by script gesture policies. View density is limited to 0.25..8; physical frames are limited to 4096 pixels per edge and 16MiB RGBA, checked before opening or resizing. Delivery keeps one pending latest frame and converts sRGB premultiplied RGBA readback to straight ARGB for Android, reusing a color array and Bitmap rather than depending on byte order or an unbounded UI frame queue. The host admits at most 32 pending public operations; excess returns RESOURCE_LIMIT, while closing bypasses that budget. UI event/script notifications are limited to 32 entries, 256KiB per entry, and 4MiB total; overflow explicitly reports RESOURCE_LIMIT and stops the generation instead of silently dropping events. The frame copy, ARGB array, and Bitmap each consume memory; native, transport, decoding, and GPU allocations are additional costs.
The example draws a self-contained GeoJSON polygon without an external map service. Applications supply layer panels, zoom/reset tools, status displays, and provider attribution using host commands/events, getStyle(), and getAttributions(). The View adds no tool panel or permanent debug label.
View source, frame helper, complete Activity example, and version/SHA manifest. The example wires lifecycle; production applications also declare network permission and display attribution required by providers.
Local evidence passes API24 Java/Activity and ARM64 JNI compilation, 18 CPU gate/conversion checks, and 15 actual JVM/JNI/software-GPU checks. A real translucent red frame (188,0,0,128) becomes Android ARGB 0x80ff0000; evidence also covers opaque blue, density resize, the 32-operation owner limit, resource cancellation, and failed-open cleanup. Framework-shim lifecycle checks are recorded separately; transparent 3D pixels remain pending. Local JVM/JNI frames do not establish Android Canvas, MotionEvent, window-lifecycle, or device-driver acceptance. Mobile GIS application integration, iOS, phone devices, and formal release remain pending.
Android host · Touch navigation · Display density · SDK acceptance
Lifecycle wiring follows the platform Activity lifecycle; pixel display uses the platform Bitmap API.