the art of building bridges for android hybrid apps

14
The Art of Building Bridges Android WebView Bridge in Depth Bartłomiej Pisulak

Upload: bartlomiej-pisulak

Post on 08-Aug-2015

144 views

Category:

Mobile


3 download

TRANSCRIPT

Page 1: The art of Building Bridges for Android Hybrid Apps

The  Art  of  Building  Bridges

Android  WebView  Bridge  in  Depth

Bartłomiej  Pisulak

Page 2: The art of Building Bridges for Android Hybrid Apps

Three  types  of  Mobile  Apps

Page 3: The art of Building Bridges for Android Hybrid Apps

Market  Share

According  to  Gartner  more  than  50%  of  mobile  apps  deployed  will  be  hybrid

Page 4: The art of Building Bridges for Android Hybrid Apps

ArchitectureIt’s  all  about  WebView…

So  what’s  the  difference?

Page 5: The art of Building Bridges for Android Hybrid Apps

The  Bridge

Bridge  between  Native  and  JS

JS  -­‐>  Native  Native  -­‐>  JS

Page 6: The art of Building Bridges for Android Hybrid Apps

JS_ObjectJavaScript  -­‐>  Java

public class WebAppInterface { Context mContext;

/** Instantiate the interface and set the context */ WebAppInterface(Context c) { mContext = c; }

/** Show a toast from the web page */ @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } }

Let’s  build  an  interface:

Page 7: The art of Building Bridges for Android Hybrid Apps

JS_ObjectJavaScript  -­‐>  Java

JS WebView

Quite  good  performance  Use  native  bridging  suggested  by  Google  

Error  prone

<script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>

WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true);

webView.addJavascriptInterface(new WebAppInterface(this), "Android");

Page 8: The art of Building Bridges for Android Hybrid Apps

Prompt JavaScript  -­‐>  Java

JS WebChromeClient

Doesn’t  crash  the  emulator  It’s  very  slow  

Overrides  default  prompt  behaviour  in  WebView  Criticised  as  antipattern

<script type="text/javascript"> prompt("toast", "This is Toast message"); </script> @Override

public boolean onJsPrompt (WebView view, String url, String message, String defaultValue, JsPromptResult result) { // message determines action if(message == "toast") { // make toast ... } }

Page 9: The art of Building Bridges for Android Hybrid Apps

loadUrl() Java  -­‐>  JavaScript  

Native JS

Quite  fast  Breaks  inputs  behaviour

<script type="text/javascript"> onLocationUpdate(int lat, int lng) { alert("Success: lat=" + lat + " lng: " + lng); } </script>

@Override public void onLocationChanged(Location location) { String lat = Double.toString(location.getLatitude()); String lng = Double.toString(location.getLongitude()); webView.loadUrl("javascript:onLocationUpdate(" + lat + "," + lng + ");"); }

Page 10: The art of Building Bridges for Android Hybrid Apps

Online  Event Java  -­‐>  JavaScript  

Native JS

It’s  fast  Even  faster  than  loadUrl()  

Doesn’t  break  anything  (yet)  Problem  in  case  of  bridging  more  than  one  WebView

<script type="text/javascript"> var handleEvent = function() { // get result from native code // using exposed interface }

window.addEventListener("online", handleEvent); window.addEventListener("offline", handleEvent); </script>

boolean flipFlop; // (...) @Override public void informJavaScriptAboutResult() { flipFlop = !flipFlop; webView.setNetworkAvailable(flipFlop); }

Page 11: The art of Building Bridges for Android Hybrid Apps

Private  APIJava  -­‐>  JavaScript  

Class webViewClass = WebView.class;

try { Field f = webViewClass.getDeclaredField("mProvider"); f.setAccessible(true); webViewObject = f.get(webView); webViewClass = webViewObject.getClass(); } catch (Throwable e) { // ... } try { Field f = webViewClass.getDeclaredField("mWebViewCore"); f.setAccessible(true); webViewCore = f.get(webViewObject);

if (webViewCore != null) { sendMessageMethod = webViewCore.getClass().getDeclaredMethod("sendMessage", Message.class); sendMessageMethod.setAccessible(true); } } catch (Throwable e) { // ... }

Be  careful  while  using  reflection…

Page 12: The art of Building Bridges for Android Hybrid Apps

Private  APIJava  -­‐>  JavaScript  

Native JS

Super  fast  Not  supported  officially  Works  on  Android  3.2+  May  break  in  the  future

<script type="text/javascript"> onLocationUpdate(int lat, int lng) { alert("Success: lat=" + lat + " lng: " + lng); } </script>

try { String js = "onLocationUpdate(" + lat + "," + lng + ");"; Message execJsMessage = Message.obtain(null, EXECUTE_JS, js); sendMessageMethod.invoke(webViewCore, execJsMessage); } catch (Throwable e) { // ... }

Page 13: The art of Building Bridges for Android Hybrid Apps

To  Sum  Up

Hybrid  is  the  future

Choose  proper  bridge

Page 14: The art of Building Bridges for Android Hybrid Apps

QA

Bartłomiej  Pisulak  Software  Engineer  |  IT  Trainer  http://www.pisulak.pl/