~eliasnaur/gio

9 4

About call java method from gio

Cloud
Details
Message ID
<CAMAftoW1A7H8bQqjd49z5pf6RfKB2tUuTMqLniFDouOt1xQUvw@mail.gmail.com>
DKIM signature
missing
Download raw message
Let me introduce what I am doing:

I am building an android app.
Before I used Flutter to build the UI, it provided a way to call Java from dart.
Now I want to change to gio.

Before, with flutter:

1. Dart: When a tap button from UI
2. Dart: Send data to MethodChannel
3. Java: Get data from MethodChannel
4. Java: Invoke method based on data (actual is string or map)
5. Java: Reply the result to MethodChannel
6. Dart: Get result and update UI

I know two ways to run gio app:

1. build a apk
2. build a aar

About 1. apk, it is so clean, I don't even need to care about anything
in java or android studio,
but we must use some java code to invoke platform-independent methods,
so maybe this way may not work.
so I am trying the 2nd way.

About 2. aar:

1. I created an empty activity android project
2. Added org.gioui.GioActivity to AndroidManifest.xml
3. Start GioActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivity(new Intent(this, GioActivity.class));
    }

    public void javamethod(datafromgio, result){

           read datafromgio

            some java platform-independent code

            result.reply(datatogio)

    }
}

Everything about the UI works well.

Question is:

When I tap a button from gio, how to let java know and invoke
javamethod, and give gio a result response.

Or maybe I should 1nd apk way?

Thank you.
Details
Message ID
<ZGW5CQ.6GD4EU2HJFOF1@sweatyballs.es>
In-Reply-To
<CAMAftoW1A7H8bQqjd49z5pf6RfKB2tUuTMqLniFDouOt1xQUvw@mail.gmail.com> (view parent)
DKIM signature
missing
Download raw message

On Fri, 19 Jun, 2020 at 15:17, Cloud <cloud@txthinking.com> wrote:
> Let me introduce what I am doing:
> 
> I am building an android app.
> Before I used Flutter to build the UI, it provided a way to call Java 
> from dart.
> Now I want to change to gio.
> 
> Before, with flutter:
> 
> 1. Dart: When a tap button from UI
> 2. Dart: Send data to MethodChannel
> 3. Java: Get data from MethodChannel
> 4. Java: Invoke method based on data (actual is string or map)
> 5. Java: Reply the result to MethodChannel
> 6. Dart: Get result and update UI
> 
> I know two ways to run gio app:
> 
> 1. build a apk
> 2. build a aar
> 
> About 1. apk, it is so clean, I don't even need to care about anything
> in java or android studio,
> but we must use some java code to invoke platform-independent methods,
> so maybe this way may not work.
> so I am trying the 2nd way.
> 
> About 2. aar:
> 
> 1. I created an empty activity android project
> 2. Added org.gioui.GioActivity to AndroidManifest.xml
> 3. Start GioActivity
> 
> public class MainActivity extends AppCompatActivity {
> 
>     @Override
>     protected void onCreate(Bundle savedInstanceState) {
>         super.onCreate(savedInstanceState);
>         startActivity(new Intent(this, GioActivity.class));
>     }
> 
>     public void javamethod(datafromgio, result){
> 
>            read datafromgio
> 
>             some java platform-independent code
> 
>             result.reply(datatogio)
> 
>     }
> }
> 
> Everything about the UI works well.
> 
> Question is:
> 
> When I tap a button from gio, how to let java know and invoke
> javamethod, and give gio a result response.
> 

That's not Gio's job, it's the language's.

This is the first thing that came up when I searched for "go java 
bindings":
https://github.com/sridharv/gojava

> Or maybe I should 1nd apk way?
> 
> Thank you.
Details
Message ID
<C3KYOLOTRJWY.421B8UHGBWAA@themachine>
In-Reply-To
<CAMAftoW1A7H8bQqjd49z5pf6RfKB2tUuTMqLniFDouOt1xQUvw@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
On Fri Jun 19, 2020 at 15:17, Cloud wrote:
> Let me introduce what I am doing:
>
> I am building an android app.
> Before I used Flutter to build the UI, it provided a way to call Java from dart.
> Now I want to change to gio.
>
> Before, with flutter:
>
> 1. Dart: When a tap button from UI
> 2. Dart: Send data to MethodChannel
> 3. Java: Get data from MethodChannel
> 4. Java: Invoke method based on data (actual is string or map)
> 5. Java: Reply the result to MethodChannel
> 6. Dart: Get result and update UI
>
> I know two ways to run gio app:
>
> 1. build a apk
> 2. build a aar
>
> About 1. apk, it is so clean, I don't even need to care about anything
> in java or android studio,
> but we must use some java code to invoke platform-independent methods,
> so maybe this way may not work.
> so I am trying the 2nd way.
>

Depending on your needs, the `gogio` tool includes all class files from
jar archives present in your main package. See

	https://git.sr.ht/~eliasnaur/gio/tree/master/cmd/gogio/androidbuild.go#L118

> About 2. aar:
>
> 1. I created an empty activity android project
> 2. Added org.gioui.GioActivity to AndroidManifest.xml
> 3. Start GioActivity
>
> public class MainActivity extends AppCompatActivity {
>
>     @Override
>     protected void onCreate(Bundle savedInstanceState) {
>         super.onCreate(savedInstanceState);
>         startActivity(new Intent(this, GioActivity.class));
>     }
>
>     public void javamethod(datafromgio, result){
>
>            read datafromgio
>
>             some java platform-independent code
>
>             result.reply(datatogio)
>
>     }
> }
>
> Everything about the UI works well.
>
> Question is:
>
> When I tap a button from gio, how to let java know and invoke
> javamethod, and give gio a result response.
>

In both the apk an aar method you'll need to use JNI to communicate across the
language barrier. Gio exports JavaVM, AppContext and Do:

	$ GOOS=android go doc gioui.org/app.AppContext
	package app // import "gioui.org/app"

	func AppContext() uintptr
	    AppContext returns the global Application context as a JNI jobject.

	$ GOOS=android go doc gioui.org/app.Do
	package app // import "gioui.org/app"

	func (w *Window) Do(f func(view uintptr))
	    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.

	$ GOOS=android go doc gioui.org/app.JavaVM
	package app // import "gioui.org/app"

	func JavaVM() uintptr
	    JavaVM returns the global JNI JavaVM.

Unfortunately, there are no Android examples in the Gio repository. For an updated example
see

	https://github.com/tailscale/tailscale-android

in particular

	https://github.com/tailscale/tailscale-android/blob/master/cmd/tailscale/main.go#L471

The tailscale-android client includes a `jni` package for making the cross-barrier calls
easier.

-- elias
Gregory Pomerantz
Details
Message ID
<d17d1c30-8316-bd4c-ea11-65f273d91296@wow.st>
In-Reply-To
<C3KYOLOTRJWY.421B8UHGBWAA@themachine> (view parent)
DKIM signature
pass
Download raw message
On 6/19/20 5:12 AM, Elias Naur wrote:

> Unfortunately, there are no Android examples in the Gio repository. For an updated example
> see
>
> 	https://github.com/tailscale/tailscale-android
>
> in particular
>
> 	https://github.com/tailscale/tailscale-android/blob/master/cmd/tailscale/main.go#L471
>
> The tailscale-android client includes a `jni` package for making the cross-barrier calls
> easier.

I have a minimal Android Fragment example here --

https://git.wow.st/gmp/android-go/src/master/examples/fragment

My Bluetooth-Low Energy library also requires a fragment to work, that 
one is published here.

https://git.wow.st/gmp/ble

Elias: the jni library is nice, you end up needing to replicate this 
functionality from project to project anyway, and your approach seems a 
bit more flexible than what I've been doing (e.g. using varArgs), any 
thoughts on forking that off into a standalone library with a stable API?
Details
Message ID
<CAFcc3FTYMKtiU0DMJYr-KYmPT0M-Dov3uDMZo2GZ9tZJ=Y8dNQ@mail.gmail.com>
In-Reply-To
<d17d1c30-8316-bd4c-ea11-65f273d91296@wow.st> (view parent)
DKIM signature
pass
Download raw message
> Elias: the jni library is nice, you end up needing to replicate this
> functionality from project to project anyway, and your approach seems a
> bit more flexible than what I've been doing (e.g. using varArgs), any
> thoughts on forking that off into a standalone library with a stable API?

+1 to this. I wanted to just import the jni package from your android
tailscale client, but there is a weird module conflict that makes it
very difficult. Specifically, attempting to import
tailscale.com/tailscale-android instead imports the module hosted at
tailscale.com directly (completely different code). The only way that
I could make it work was a replace directive, and that's really
unpleasant in library code. I'd love a jni package like that either in
gio or standalone.

Cheers,
Chris
Details
Message ID
<C3LCDGR8MPQB.18UJV8FHG1JNC@themachine>
In-Reply-To
<d17d1c30-8316-bd4c-ea11-65f273d91296@wow.st> (view parent)
DKIM signature
pass
Download raw message
On Fri Jun 19, 2020 at 15:10, Gregory Pomerantz wrote:
> On 6/19/20 5:12 AM, Elias Naur wrote:
>
> > Unfortunately, there are no Android examples in the Gio repository. For an updated example
> > see
> >
> > 	https://github.com/tailscale/tailscale-android
> >
> > in particular
> >
> > 	https://github.com/tailscale/tailscale-android/blob/master/cmd/tailscale/main.go#L471
> >
> > The tailscale-android client includes a `jni` package for making the cross-barrier calls
> > easier.
>
> Elias: the jni library is nice, you end up needing to replicate this 
> functionality from project to project anyway, and your approach seems a 
> bit more flexible than what I've been doing (e.g. using varArgs), any 
> thoughts on forking that off into a standalone library with a stable API?

A separate package is a good idea, except that I don't want to spend the
bandwidth to maintain it, at least not yet. Sorry. FWIW, the tailscale version
is open source if you or anyone else would like to carry the torch.

-- elias
Gregory Pomerantz
Details
Message ID
<b5a722da-6fb0-4805-9189-ce01026704b8@wow.st>
In-Reply-To
<C3LCDGR8MPQB.18UJV8FHG1JNC@themachine> (view parent)
DKIM signature
pass
Download raw message
> A separate package is a good idea, except that I don't want to spend the
> bandwidth to maintain it, at least not yet. Sorry. FWIW, the tailscale version
> is open source if you or anyone else would like to carry the torch.

Sounds fair, I was about to raise my hand and volunteer for that anyway, 
we'll see how it goes.

https://git.wow.st/gmp/jni
Details
Message ID
<C3LCTSKN17K0.RQWBT06VCBVS@themachine>
In-Reply-To
<b5a722da-6fb0-4805-9189-ce01026704b8@wow.st> (view parent)
DKIM signature
pass
Download raw message
On Fri Jun 19, 2020 at 16:11, Gregory Pomerantz wrote:
>
> > A separate package is a good idea, except that I don't want to spend the
> > bandwidth to maintain it, at least not yet. Sorry. FWIW, the tailscale version
> > is open source if you or anyone else would like to carry the torch.
>
> Sounds fair, I was about to raise my hand and volunteer for that anyway, 
> we'll see how it goes.
>
> https://git.wow.st/gmp/jni

Thank you!

-- elias

JNI library: git.wow.st/gmp/jni

Gregory Pomerantz
Details
Message ID
<989eaa97-9c3e-9b2e-8ec4-d01222a16ccc@wow.st>
In-Reply-To
<C3LCTSKN17K0.RQWBT06VCBVS@themachine> (view parent)
DKIM signature
pass
Download raw message
On 6/19/20 4:17 PM, Elias Naur wrote:
>> Sounds fair, I was about to raise my hand and volunteer for that anyway,
>> we'll see how it goes.
>>
>> https://git.wow.st/gmp/jni
> Thank you!

I added tests, ports to MacOS and Linux (needed to locate the header 
files and linker flag) as well as the CreateJavaVM function so you can 
spin up a new JVM right from Go (though Google does not let you do this 
on Android). Chris Waldon contributed the accessors, so this is starting 
to get fleshed out a bit.

You can try "go test -cpu 4 -count 2000" and let me know how it goes. On 
Linux I have to manually set LD_LIBRARY_PATH to find libjvm.so, not sure 
why that's necessary.

Re: JNI library: git.wow.st/gmp/jni

Details
Message ID
<C3OC5B0W6DTC.1QQK05IEUQ2Y3@themachine>
In-Reply-To
<989eaa97-9c3e-9b2e-8ec4-d01222a16ccc@wow.st> (view parent)
DKIM signature
pass
Download raw message
On Mon Jun 22, 2020 at 23:22, Gregory Pomerantz wrote:
> On 6/19/20 4:17 PM, Elias Naur wrote:
> >> Sounds fair, I was about to raise my hand and volunteer for that anyway,
> >> we'll see how it goes.
> >>
> >> https://git.wow.st/gmp/jni
> > Thank you!
>
> I added tests, ports to MacOS and Linux (needed to locate the header 
> files and linker flag) as well as the CreateJavaVM function so you can 
> spin up a new JVM right from Go (though Google does not let you do this 
> on Android). Chris Waldon contributed the accessors, so this is starting 
> to get fleshed out a bit.
>
> You can try "go test -cpu 4 -count 2000" and let me know how it goes. On 
> Linux I have to manually set LD_LIBRARY_PATH to find libjvm.so, not sure 
> why that's necessary.

Nice!

-- elias
Export thread (mbox)