Hybrid apps combine the familiarity and depth of native facilities while at the same time allowing extensibility via embedded web views. Your Angular code needs to talk back and forth to your native code to exchange data. This talk goes through how to implement this communication on both Android and iOS. We will cover the basics of how to allow Java/Objective-C to talk to JavaScript running in a web view and also how to bring Angular into the mix.
7. Java to JavaScript
API
void evaluateJavascript(String script, ValueCallback<String> resultCallback)
webView.evaluateJavascript(“someJavaScriptFunction();”, new ValueCallback<String>() {
public void onReceiveValue(String s) {
JsonReader reader = new JsonReader(new StringReader(s));
JsonToken token = JsonReader.peek()
...
}
});
Usage
8. Java to JavaScript
Requirements
1. API level 19.
2. WebSettings.setJavaScriptEnabled(true) // false by default
3. Must be called on UI thread.
evaluateJavascript(...)
Properties
1. Asynchronous evaluation.
2. Context of currently displayed page.
3. Callback made on UI thread.
4. Callback value is a JSON object. To pass String values use
JsonReader.setLenient(true).
9. Java to JavaScript - Pre 19
void loadUrl(String url)
Usage
webView.loadUrl(“javascript:someJsFunction();”);
API
Pitfall - Navigate away
webView.loadUrl(“javascript:someJsFunction();void(0);”);
No return value!
11. JavaScript to Java
Inject objects into the displayed page context:
private final class Api {
public void showMessage(String message) {
Log.d(TAG, message);
}
}
webView.addJavascriptInterface(new Api(), "MyJavaObj");
Starting API 17
void addJavascriptInterface(Object serviceApi, String name)
Usage
API
MyJavaObj.showMessage(“Hello There!”);
JavaJS
@JavascriptInterface
12. JavaScript to Java - Notes
1. Injected objects will not appear in JavaScript until the page is next (re)loaded.
webView.loadData("", "text/html", null);
2. WebView interacts with Java object on a background thread.
3. Serialization of arguments
a. Simple types and strings
b. Serialize objects as JSON
4. Use WebChromeClient to handle callbacks
webView.setWebChromeClient(new WebChromeClient() {
public boolean onJsAlert(...) {
// display alert in OS theme
}
});
}
13. Troubleshooting
Use Chrome “Inspect” feature
chrome://inspect
Must enable debugging
WebView.setWebContentsDebuggingEnabled(true);
[INFO:CONSOLE(1)] "Uncaught SyntaxError: Unexpected token ILLEGAL", source: (1)
[INFO:CONSOLE(13)] "Uncaught ReferenceError: MyJavaObj is not defined"
android.view.ViewRootImpl$CalledFromWrongThreadException
1. Run calls from JavaScript on UI Thread.
2. Wait till page loads WebViewClient.onPageFinished()
3. Force page load using
webView.loadData("", "text/html", null);
Debugging
Common Causes
Common Errors
22. Angular to Native
Wrap an Angular service around the injected Object.
angular.module('MyModule').service('WrapperService', function() {
this.showMessage = function(message) {
MyInjectedObj.showMessage(message);
};
this.someOtherMethod = function() {
MyInjectedObj.someOtherMethod();
};
});
23. Java to Angular
// Get the element for the angular application
var app = angular.element('[ng-app]');
// Get the injector from the application
var injector = app.injector();
// Get the service to be called
var myService = injector.get("MyService");
// Invoke the service
myService.someFunction();
What is the entry point from plain JavaScript to Angular?
24. Appreciate what PhoneGap does for you!
Summary
● Hybrid Apps
● Conversing with the Web View
● Extensions
○ Other platforms
○ Callbacks to JavaScript
○ Code generation