Slide 72 of 74

Packaging an app

A program that is also an app
type Msg {
	Tapped
}

func view(count: Int): ui.View {
	return ui.column([ui.pad(24), ui.gap(12), ui.align(ui.Align.Center())], [
		ui.text([ui.size(ui.TextSize.Title())], "Tapped {count} times"),
		ui.button([ui.on(Msg.Tapped()), ui.tone(ui.Tone.Good())], "Tap"),
	])
}

proc update(count: mut Int, msg: Msg): Msg {
	if msg is Msg.Tapped {
		count += 1
	}
	return msg
}

proc main(): void {
	spawn(ui.window("Taps", view, update), 0)
}
Run it here, install it there
$ hive run taps.hive          # a window on this machine
$ hive export taps.hive --target android/arm64
Packaged taps.hive -> taps-android-arm64.apk (4s)

$ adb install taps-android-arm64.apk
Success
The four ways it says no
$ hive export taps.hive
hive: `hive export` needs a target, and the one it knows is `--target android/arm64`.

$ hive export taps.hive --target android/amd64
hive: `--target android/amd64` needs a C cross-compiler, which is the one thing a machine with the Go toolchain on it cannot be assumed to have. `android/arm64` is the only Android target Go links on its own, and it is what a handset is.

$ hive export taps.hive --target linux/arm64
hive: `hive export` knows one format, and it is Android's. It takes `--target android/arm64`; `linux/arm64` has no app to be packaged into.

$ hive export server.hive --target android/arm64
server.hive:1: `server.hive` opens no window, so there is nothing for an app to show and no way to start it. `hive build` is what compiles a program that serves or prints.

hive build writes a program. hive export writes an app: hive export taps.hive --target android/arm64 produces taps-android-arm64.apk, installable as it stands.

The window needs nothing new. A hive.ui.window already serves its own page over loopback with every asset embedded, so what shows it on a handset is the WebView the platform already has. The program is never told it is on a phone: it serves the tree it would serve a browser, and the same view answers both.

  • android/arm64, and no other Android target. It is the only one Go links without a C cross-compiler, so the other three are refused by name — and it is what a handset is.
  • A program with no window is refused rather than packaged: an app that shows nothing has no way to be started. hive build is what compiles a program that serves or prints.
  • Nothing but Go writes it. The file holds the program, a fixed WebView host, a binary manifest, and assets/icon.png as the launcher icon where the program ships one. The manifest, the resource table, the archive and its signature are the build's own work: no Android SDK, and no network.
  • The application id comes from the entrypoint's name: taps.hive is hive.taps. Two apps whose entrypoints are both main.hive are one app to the phone, and the second installs over the first — name the entrypoint after the app.

The signature is APK Signature Scheme v2, under a key made on first use at ~/.hive/android.key. One stable key per machine, so a later build installs over an earlier one instead of being refused as a different app.