hybrid apps: java conversing with javascript

16
Hybrid Apps with Angular: Java conversing with JavaScript Ayman Mahfouz VP of Engineering @ Webalo September 2016

Upload: ayman-mahfouz

Post on 12-Apr-2017

108 views

Category:

Software


1 download

TRANSCRIPT

Hybrid Apps with Angular: Java

conversing with JavaScriptAyman Mahfouz

VP of Engineering @ Webalo

September 2016

Problem Context - Webalo Platform

Problem Context - Webalo App

Shared Java code allows for extensibility, but how to open the Webalo Client up for third party extension?

Solution - Hybrid App

HTML + JavaScript

Java

WebView

Android App

● Java: Proprietary code.● JavaScript: Third-party code.

Java to JavaScript

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

Java to JavaScript

Requirements

1. API level 19.2. WebSettings.setJavaScriptEnabled(true) // false by default3. 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).

JavaScript to Java

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 GDG!”);

Java

JS

@JavascriptInterface

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 stringsb. Serialize objects as JSON

4. Use WebChromeClient to handle callbacks

webView.setWebChromeClient(new WebChromeClient() { public boolean onJsAlert(...) { // display alert in OS theme } }); }

Troubleshooting

Use Chrome “Inspect” feature

chrome://inspectMust 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

The Angular bit

Angular to Java

Wrap an Angular service around the injected Java Object.

angular.module('MyModule').service('WrapperService', function() { this.showMessage = function(message) { MyJavaObj.showMessage(message); };

this.someOtherMethod = function() { MyJavaObj.someOtherMethod(); };});

Java to Angular

// Get the element for the angular applicationvar app = angular.element('[ng-app]');

// Get the injector from the application var injector = app.injector();

// Get the service to be calledvar myService = injector.get("MyService");

// Invoke the servicemyService.someFunction();

What is the entry point from plain JavaScript to Angular?