2014-08-21 16:07:33 -04:00
|
|
|
// Copyright 2014 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
/*
|
2015-07-06 16:42:47 -06:00
|
|
|
Package app lets you write portable all-Go apps for Android and iOS.
|
2014-08-21 16:07:33 -04:00
|
|
|
|
2015-07-06 16:42:47 -06:00
|
|
|
There are typically two ways to use Go on Android and iOS. The first
|
|
|
|
is to write a Go library and use `gomobile bind` to generate language
|
|
|
|
bindings for Java and Objective-C. Building a library does not
|
|
|
|
require the app package. The `gomobile bind` command produces output
|
|
|
|
that you can include in an Android Studio or Xcode project. For more
|
|
|
|
on language bindings, see https://golang.org/x/mobile/cmd/gobind.
|
2014-08-21 16:07:33 -04:00
|
|
|
|
2015-07-06 16:42:47 -06:00
|
|
|
The second way is to write an app entirely in Go. The APIs are limited
|
|
|
|
to those that are portable between both Android and iOS, in particular
|
|
|
|
OpenGL, audio, and other Android NDK-like APIs. An all-Go app should
|
|
|
|
use this app package to initialze the app, manage its lifecycle, and
|
|
|
|
receive events.
|
2014-08-21 16:07:33 -04:00
|
|
|
|
2015-07-06 16:42:47 -06:00
|
|
|
Building apps
|
2014-08-21 16:07:33 -04:00
|
|
|
|
2015-07-06 16:42:47 -06:00
|
|
|
Apps written entirely in Go have a main function, and can be built
|
|
|
|
with `gomobile build`, which directly produces runnable output for
|
|
|
|
Android and iOS.
|
2014-08-21 16:07:33 -04:00
|
|
|
|
2015-08-12 12:09:41 -04:00
|
|
|
The gomobile tool can get installed with go get. For reference, see
|
2015-07-06 16:42:47 -06:00
|
|
|
https://golang.org/x/mobile/cmd/gomobile.
|
2014-08-21 16:07:33 -04:00
|
|
|
|
2015-08-12 12:09:41 -04:00
|
|
|
For detailed instructions and documentation, see
|
|
|
|
https://golang.org/wiki/Mobile.
|
|
|
|
|
2015-07-06 16:42:47 -06:00
|
|
|
Event processing in Native Apps
|
2014-08-21 16:07:33 -04:00
|
|
|
|
2015-07-16 15:53:00 +10:00
|
|
|
The Go runtime is initialized on Android when NativeActivity onCreate is
|
|
|
|
called, and on iOS when the process starts. In both cases, Go init functions
|
|
|
|
run before the app lifecycle has started.
|
2014-08-21 16:07:33 -04:00
|
|
|
|
2015-07-16 15:53:00 +10:00
|
|
|
An app is expected to call the Main function in main.main. When the function
|
|
|
|
exits, the app exits. Inside the func passed to Main, call Filter on every
|
|
|
|
event received, and then switch on its type. Registered filters run when the
|
|
|
|
event is received, not when it is sent, so that filters run in the same
|
|
|
|
goroutine as other code that calls OpenGL.
|
2014-08-21 16:07:33 -04:00
|
|
|
|
|
|
|
package main
|
|
|
|
|
2014-09-03 09:03:00 -04:00
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
|
2014-11-10 08:55:57 +11:00
|
|
|
"golang.org/x/mobile/app"
|
2015-07-15 17:17:08 +10:00
|
|
|
"golang.org/x/mobile/event/lifecycle"
|
|
|
|
"golang.org/x/mobile/event/paint"
|
2014-09-03 09:03:00 -04:00
|
|
|
)
|
2014-08-21 16:07:33 -04:00
|
|
|
|
|
|
|
func main() {
|
2015-07-06 16:42:47 -06:00
|
|
|
app.Main(func(a app.App) {
|
|
|
|
for e := range a.Events() {
|
2015-09-22 13:19:05 -04:00
|
|
|
switch e := a.Filter(e).(type) {
|
2015-07-15 17:17:08 +10:00
|
|
|
case lifecycle.Event:
|
2015-07-06 16:42:47 -06:00
|
|
|
// ...
|
2015-07-15 17:17:08 +10:00
|
|
|
case paint.Event:
|
2015-07-06 16:42:47 -06:00
|
|
|
log.Print("Call OpenGL here.")
|
app: change EndPaint to Publish.
More than a name change, the painting model changes so that the app, not
the library, is responsible for driving painting. If the app is
animating and wants paint events at 60 Hz, it has to ask for that. If
the app is not animating and doesn't need to update its screen, it
shouldn't get any paint events.
Plenty of TODOs, and this CL doesn't get us to a perfect place, but it
is a checkpoint along the way.
The darwin_*.go code changes were minimal. I don't even have a Mac or
iOS device to test that this even builds. Even so, the TODOs about not
sending paint.Events unconditionally are important TODOs. That's the
whole point of switching to this model. I'll leave the actual
implementation to you (crawshaw).
Out of all the example apps, the change to example/network/main.go is
probably the most interesting.
It seems like there ought to be some way to reduce the copy/paste
between all of the example app code, but I'll leave that for future CLs.
Change-Id: I17e11c06174110c68e17f7183b2d8af19b6a170e
Reviewed-on: https://go-review.googlesource.com/14300
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-09-04 17:13:09 +10:00
|
|
|
a.Publish()
|
2015-07-06 16:42:47 -06:00
|
|
|
}
|
|
|
|
}
|
2014-09-09 19:51:04 -04:00
|
|
|
})
|
2014-09-03 09:03:00 -04:00
|
|
|
}
|
|
|
|
|
2015-07-16 15:53:00 +10:00
|
|
|
An event is represented by the empty interface type interface{}. Any value can
|
|
|
|
be an event. Commonly used types include Event types defined by the following
|
|
|
|
packages:
|
|
|
|
- golang.org/x/mobile/event/lifecycle
|
2015-07-27 13:45:14 +10:00
|
|
|
- golang.org/x/mobile/event/mouse
|
2015-07-16 15:53:00 +10:00
|
|
|
- golang.org/x/mobile/event/paint
|
2015-08-13 19:59:18 +10:00
|
|
|
- golang.org/x/mobile/event/size
|
2015-07-16 15:53:00 +10:00
|
|
|
- golang.org/x/mobile/event/touch
|
|
|
|
For example, touch.Event is the type that represents touch events. Other
|
|
|
|
packages may define their own events, and send them on an app's event channel.
|
|
|
|
|
|
|
|
Other packages can also register event filters, e.g. to manage resources in
|
|
|
|
response to lifecycle events. Such packages should call:
|
|
|
|
app.RegisterFilter(etc)
|
|
|
|
in an init function inside that package.
|
2014-08-21 16:07:33 -04:00
|
|
|
*/
|
2014-12-09 14:07:24 +11:00
|
|
|
package app // import "golang.org/x/mobile/app"
|