mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 01:45:36 +00:00
app/internal/window: [Android] replace RegisterFragment with Do
Do is a function for accessing the underlying Android View in a safe context, the main thread. Do is - more general than RegisterFragment and may be expanded to other platforms - simpler to implement (from the Gio side) and as a bonus, the Do implementation avoids a race condition where a call to RegisterFragment during an Activity re-create would be ignored. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+28
-14
@@ -17,18 +17,32 @@ func AppContext() uintptr {
|
||||
return window.AppContext()
|
||||
}
|
||||
|
||||
// androidDriver is an interface that allows the Window's run method
|
||||
// to call the RegisterFragment method of the Android window driver.
|
||||
type androidDriver interface {
|
||||
RegisterFragment(string)
|
||||
}
|
||||
|
||||
// RegisterFragment constructs a Java instance of the specified class
|
||||
// and registers it as a Fragment in the Context in which the View was
|
||||
// created.
|
||||
func (w *Window) RegisterFragment(del string) {
|
||||
w.driverDo(func() {
|
||||
d := w.driver.(androidDriver)
|
||||
d.RegisterFragment(del)
|
||||
})
|
||||
// Do invokes the function with a JNI jobject handle to the underlying
|
||||
// Android View. The function is invoked on the main thread, and the
|
||||
// handle is invalidated after the function returns.
|
||||
//
|
||||
// Note: Do may deadlock if called from the same goroutine that receives from
|
||||
// Events.
|
||||
func (w *Window) Do(f func(view uintptr)) {
|
||||
type androidDriver interface {
|
||||
Do(f func(view uintptr)) bool
|
||||
}
|
||||
success := make(chan bool)
|
||||
for {
|
||||
driver := make(chan androidDriver, 1)
|
||||
// two-stage process: first wait for a valid driver...
|
||||
w.driverDo(func() {
|
||||
driver <- w.driver.(androidDriver)
|
||||
})
|
||||
// .. then run the function on the main thread using the
|
||||
// driver. The driver Do method returns false if the
|
||||
// view was invalidated while switching to the main thread.
|
||||
window.RunOnMain(func() {
|
||||
d := <-driver
|
||||
success <- d.Do(f)
|
||||
})
|
||||
if <-success {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user