zermatt zermatt - 7 months ago 87
Javascript Question

How compatible is JavaFX Webview with Android's Webview?

I've been trying to port a JavaFX project using Netbeans and Gradle into an Android APK file format and for the most part it works well! The issue I'm having is with the WebView component of Android in particular? I can get it to show a static webpage in Android Webview without my app falling over with a FATAL EXCEPTION. But if I create a dynamic webpage in JavaFX Webview using JavaScript, Androids Webview doesn't appear to cope at all?

Eventhough in JavaFX I set enable JavaScript to true:

googleMapEngine.setJavaScriptEnabled(true);


As I'm aware that in Android Webview - JavaScript is switched off by default.
I cannot get it to work in Android. In addition, does Android Webview know how to resolve the JavaFX command?

googleMapEngine.executeScript(String);


Cause if I try this:

googleMapEngine.executeScript(
"var latlng = new google.maps.LatLng(59.438722, 24.745278);" +
"var myOptions = {" +
"zoom: 15," +
"center: latlng," +
"mapTypeId: google.maps.MapTypeId.ROADMAP," +
"mapTypeControl: false," +
"navigationControl: false," +
"streetViewControl: false," +
"backgroundColor: '#666970'," +
"disableDefaultUI: true" +
"};" +
"" +
"var map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);");


I end up with error in logcat:

I/System.out( 809): [JVDBG] Error firing event

W/System.err( 809): java.lang.ClassNotFoundException: com.sun.webkit.NativeWebView

W/System.err( 809): at java.lang.Class.classForName(Native Method)

W/System.err( 809): at java.lang.Class.forName(Class.java:309)

W/System.err( 809): at com.oracle.dalvik.InternalWebView._fireLoadEvent(InternalWebView.java:347)

W/System.err( 809): at com.oracle.dalvik.InternalWebView.fireLoadEvent(InternalWebView.java:140)

W/System.err( 809): at com.oracle.dalvik.InternalWebView.access$400(InternalWebView.java:43)

W/System.err( 809): at com.oracle.dalvik.InternalWebView$MyJavaScriptInterface.processHTML(InternalWebView.java:363)

W/System.err( 809): at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)

W/System.err( 809): at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:39)

W/System.err( 809): at android.os.Handler.dispatchMessage(Handler.java:102)

W/System.err( 809): at android.os.Looper.loop(Looper.java:145)

W/System.err( 809): at android.os.HandlerThread.run(HandlerThread.java:61)

W/System.err( 809): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.sun.webkit.NativeWebView" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]

W/System.err( 809): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)

W/System.err( 809): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)

W/System.err( 809): at java.lang.ClassLoader.loadClass(ClassLoader.java:469)

W/System.err( 809): ... 11 more

W/System.err( 809): Suppressed: java.lang.ClassNotFoundException: com.sun.webkit.NativeWebView

W/System.err( 809): at java.lang.Class.classForName(Native Method)

W/System.err( 809): at java.lang.BootClassLoader.findClass(ClassLoader.java:781)

W/System.err( 809): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)

W/System.err( 809): at java.lang.ClassLoader.loadClass(ClassLoader.java:504)

W/System.err( 809): ... 12 more

W/System.err( 809): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

E/AndroidRuntime( 809): FATAL EXCEPTION: JavaFX Application Thread

E/AndroidRuntime( 809): Process: com.SundaeThePugApp, PID: 809

E/AndroidRuntime( 809): java.lang.UnsupportedOperationException: Not supported yet.

E/AndroidRuntime( 809): at com.sun.webkit.WebPage.executeScript(WebPage.java:153)

E/AndroidRuntime( 809): at javafx.scene.web.WebEngine.executeScript(WebEngine.java:860)

E/AndroidRuntime( 809): at com.SundaeThePugApp.SundaeThePugController$1.changed(SundaeThePugController.java:202)

E/AndroidRuntime( 809): at com.SundaeThePugApp.SundaeThePugController$1.changed(SundaeThePugController.java:200)

E/AndroidRuntime( 809): at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)

E/AndroidRuntime( 809): at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)

E/AndroidRuntime( 809): at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:176)

E/AndroidRuntime( 809): at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:142)

E/AndroidRuntime( 809): at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)

E/AndroidRuntime( 809): at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)

E/AndroidRuntime( 809): at javafx.scene.web.WebEngine$LoadWorker.updateState(WebEngine.java:1023)

E/AndroidRuntime( 809): at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1134)

E/AndroidRuntime( 809): at javafx.scene.web.WebEngine$LoadWorker.access$1000(WebEngine.java:1016)

E/AndroidRuntime( 809): at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1003)

E/AndroidRuntime( 809): at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:251)

E/AndroidRuntime( 809): at com.sun.webkit.NativeWebView$1.run(NativeWebView.java:100)

E/AndroidRuntime( 809): at com.sun.javafx.application.PlatformImpl.lambda$null$155(PlatformImpl.java:295)

E/AndroidRuntime( 809): at com.sun.javafx.application.PlatformImpl.access$lambda$18(PlatformImpl.java)

E/AndroidRuntime( 809): at com.sun.javafx.application.PlatformImpl$$Lambda$19.run(Unknown Source)

E/AndroidRuntime( 809): at java.security.AccessController.doPrivileged(AccessController.java:52)

E/AndroidRuntime( 809): at com.sun.javafx.application.PlatformImpl.lambda$runLater$156(PlatformImpl.java:294)

E/AndroidRuntime( 809): at com.sun.javafx.application.PlatformImpl.access$lambda$5(PlatformImpl.java)

E/AndroidRuntime( 809): at com.sun.javafx.application.PlatformImpl$$Lambda$6.run(Unknown Source)

E/AndroidRuntime( 809): at com.sun.glass.ui.monocle.RunnableProcessor.runLoop(RunnableProcessor.java:92)

E/AndroidRuntime( 809): at com.sun.glass.ui.monocle.RunnableProcessor.run(RunnableProcessor.java:51)

E/AndroidRuntime( 809): at java.lang.Thread.run(Thread.java:818)

V/ApplicationPolicy( 3468): isApplicationStateBlocked userId 0 pkgname com.SundaeThePugApp

V/ApplicationPolicy( 3468): isApplicationStateBlocked userId 0 pkgname com.SundaeThePugApp

V/ApplicationPolicy( 3468): isApplicationStateBlocked userId 0 pkgname com.sec.android.app.launcher


All feedback will be most welcomed :)

Answer

OK after much trial and errors I have come to the conclusion that JavaFXPorts on the whole is damn good, but their are some caveats:

1) Media and Audio capabilities are not possible with your app at present as it throws a Fatal Exception.

2) Webview is limited to rendering non javascript websites.

I'll explain, if I use:

googleMapEngine.load("http://fxexperience.com/");

Perfect, everything works fine and the page is rendered properly.

But if I do this:

googleMapEngine.setJavaScriptEnabled(true);    
googleMapEngine.load("https://www.openstreetmap.org/");

I get NO map and all I can see in my app is the open street map logo and a menu button, otherwise the rest of the webview is white! Also enabling JavaScript in JavaFX seems to have no effect on Androids webview leaving Androids default setting to false!

What about if I do the most simplest Google Map url possible:

googleMapEngine.setJavaScriptEnabled(true);    
googleMapEngine.load("https://www.google.com/maps/");

I get nothing but a white screen! Also enabling JavaScript in JavaFX seems to have no effect on Androids webview leaving Androids default setting to false!

if I do a local html file with its path correctly made:

googleMapEngine.setJavaScriptEnabled(true);
googleMapEngine.load(getClass().getClassLoader().getResource("googleLondonMap.html").toExternalForm());

I receive a net::ERR_UNKNOWN_URL_SCHEME in the Android webview.

Finally, as Androids Webview default javascript setting is set to false. This means if ever you try to use JavaFX statement:

googleMapEngine.executeScript(foo());

It will cause a FATAL EXCEPTION in your android app. It would be sweet if Johan Vos and Co can overcome these Android WebView porting issues with future updates to their excellent work on JavaFXPorts!

Comments