Closed newk5 closed 10 months ago
Can you provide some actual code to reproduce? This is what I've tried and it seems to work completely fine:
Webview wv = new Webview(true); // Can optionally be created with an AWT component to be painted on.
wv.bind("test", (arguments) -> {
System.out.println(arguments);
return null;
});
wv.setTitle("My Webview App");
wv.setSize(800, 600);
new Thread(() -> {
try {
Thread.sleep(5000); // Wait 5s.
} catch (InterruptedException ignored) {}
wv.dispatch(() -> {
wv.eval("test('Hello world!');");
});
}).start();
wv.loadURL("https://example.com");
wv.run();
wv.close();
basically, this code creates an async thread which waits 5 seconds and then calls a bind() handler.
Sorry it seems that the issue was on my end, was calling .dispatch() too soon before the webview had been completely initialized.
This code is a bit different than the situation I described on my post, it spawns the webview in a different and thread uses the main thread to call dispatch, but it does reproduce the issue:
static Webview wv = null;
public static void main(String[] args) throws InterruptedException {
AtomicBoolean ready = new AtomicBoolean(false);
Thread t = new Thread(() -> {
wv = new Webview(true);
wv.setTitle("My Webview App");
wv.setSize(800, 600);
wv.loadURL("file:///C:/index.html");
wv.bind("test", arg -> {
System.out.println("Called test");
return null;
});
ready.set(true);
wv.run();
wv.close();
});
t.start();
//block here until ready is set to true
while (!ready.get()){}
wv.dispatch(() -> {
wv.eval("loadData('Hello world!');");
});
t.join();
}
index.html has a function like this:
<script>
async function loadData(data) {
alert("called loadData");
await test(); //call java
}
</script>
Instead of doing a .sleep() I was using an atomic boolean to wait for the the webview to be ready but since I can't set the boolean to true after .run() since that call is blocking, I set it to true after doing the .bind(). But it was too soon and caused the issue. I guess we dont have a direct way to know from java's side when the webview is ready, othen than calling a java function from javascript in some events like "DOMContentLoaded". But it's fine not really a big issue.
Hello, what is the recomended way to interact with the webview from a different thread?
Imagine the following use case:
Since webview.eval cannot be used from a different thread I'm currently doing this from the background thread:
This is currently working for me but it has one problem. When calling webview.eval() inside webview.dispatch(), java functions that were binded with webview.bind() do not run. For example if my "etc" variable there contains some javascript code that calls a function that I binded with webview.bind, it wont call the java side. I also noticed on the code it says dispatch is deprecated so I dont understand if there is another way to do this type of thing, or if its planned for the future.