when web meet native app

44
Page Title SUBTITLE 1 When Web meet Na6ve App Eric Chuang 當網遇上原App

Upload: eric-chuang

Post on 20-Aug-2015

2.851 views

Category:

Engineering


4 download

TRANSCRIPT

Page 1: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Page  Title

SUBTITLE

1

When    Web  meet    Na6ve  App

Eric  Chuang

當網⾴頁遇上原⽣生App

Page 2: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

When  Web  meet  Na6ve  App

Yahoo  Taiwan  Mobile  Team  Eric  Chuang

2

Page 3: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

About  Me• Eric  Chuang  (ddsakura)  • WebConf  2012  Speaker  • Yahoo  Lead  Engineer

3

• Full  Stack  Engineer  ?  – Developed  Yahoo  E-­‐Commerce  Mobile  Web  – Developed  Yahoo  E-­‐Commerce  超級商城  iPhone  App  – Developed  Yahoo  E-­‐Commerce  拍賣  Android  App

Page 4: When Web meet Native App

Auc6on  Android  App

Page 5: When Web meet Native App

猜猜哪裡是  Web?

Page 6: When Web meet Native App

Web  in  Auc6on  Android  App

Page 7: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

What  is  Webview• A  View  that  displays  web  pages.  • Android  

– Since  API  1  

• iOS  – UIWebView  – MKWebView

7

Page 8: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

曾經我以為Android  Webview  >  iOS  UIWebview                                                                                                (can  not  use  Nitro  JavaScript  Engine  )

8

Android  Webview  ==  Android  Browser

Page 9: When Web meet Native App

CONFIDENTIAL & PROPRIETARY 9hWp://beta.html5test.com/

Page 10: When Web meet Native App

CONFIDENTIAL & PROPRIETARY hWp://beta.html5test.com/

Page 11: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

結果…

11

Android  Webview  !=  Android  Browser

Android  Webview  v.s.  iOS  UIWebview/MKWebview

Page 12: When Web meet Native App

CONFIDENTIAL & PROPRIETARY 12

Page 13: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Android  Webview  version• Android  4.4  

– Chromium  30

13

• Android  4.4.3  – Chromium  33

• Android  5.0  – Chromium  37

• And  in  google  play  – hWps://play.google.com/store/apps/details?id=com.google.android.webview  

Page 14: When Web meet Native App

CONFIDENTIAL & PROPRIETARY 14

Page 15: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Android  Webview  version• Android  before  4.4  

– Old  Webview  – Vendor  may  “improve”  their  webview  – ref:  hWp://slides.com/html5test/the-­‐android-­‐browser#/12

15

Page 16: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

SO  WE  NO  LONGER  HAVE  ONE  WEBVIEW  FOR  EACH  ANDROID  VERSIONBUT

16

ONE  FOR  SAMSUNG,

AND  ONE  FOR  HTC,

AND  ONE  FOR  ...

Page 17: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Let’s  start  webview• We  need  permission

17

<uses-­‐permission  android:name="android.permission.INTERNET"  />

• Basic  usageWebView  mWebview  =  new  WebView(this);  

mWebview.loadUrl(“file:///android_asset/www/index.html”);  

mWebview.loadUrl(“hWp://tw.yahoo.com/“);  

String  summary  =  “<html><body>Hello  World</body></html>”;  mWebview.loadData(summary,  "text/html",  null);  

Page 18: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Local  Assets• file:///android_asset/  

– The  assets  directory  of  an  Android  app  is  located  at                                                        src/main/assets  inside  your  Android  Studio  project.

18

Page 19: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

How  about  JavaScript• WebViews  don't  allow  JavaScript  by  default.

19

//  Enable  JavascriptWebSepngs    webSepngs  =  mWebView.getSepngs();  webSepngs.setJavaScriptEnabled(true);

Page 20: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Configure  webview• Websepngs  

– setJavaScriptEnabled    • The  default  is  false.  

– setGeoloca6onEnabled    • The  default  is  true.    • ACCESS_COARSE_LOCATION,  ACCESS_FINE_LOCATION  

– setBuiltInZoomControls    • The  default  is  false.    

– setDomStorageEnabled    • The  default  value  is  false.

20hWp://developer.android.com/reference/android/webkit/WebSepngs.html

Page 21: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Configure  webview  cont.• UserAgent  

– getUserAgentString  – setUserAgentString

21

Mozilla/5.0  (Linux;  U;  Android  4.1.1;  en-­‐gb;  Build/KLP)  AppleWebKit/534.30  (KHTML,  like  Gecko)  Version/4.0  Safari/534.30

Mozilla/5.0  (Linux;  Android  4.4;  Nexus  5  Build/_BuildID_)  AppleWebKit/537.36  (KHTML,  like  Gecko)  Version/4.0  Chrome/30.0.0.0  Mobile  Safari/537.36

hWps://developer.chrome.com/mul6device/user-­‐agent

Page 22: When Web meet Native App

WebViewClient

WebChromeClient

Page 23: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

WebViewClient• Instance  of  WebViewClient  that  is  the  client  callback.  • It  will  be  called  when  things  happen  that  impact  the  

rendering  of  the  content,  • Func6ons  

– onLoadResource  – onPageStart  – onPageFinish  – onReceiveError  – shouldInterceptRequest  

23hWp://developer.android.com/reference/android/webkit/WebViewClient.html

Page 24: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

WebChromeClient• Instance  of  WebChromeClient  for  handling  all  chrome  

func6ons.  • This  class  is  called  when  something  that  might  impact  a  

browser  UI  happens,  for  instance,  progress  updates  and  JavaScript  alerts  are  sent  here    

• Func6ons  – onCloseWindow  – onCreateWindow  – onJsAlert  – onJsPrompt  – onJsConfirm  

24hWp://developer.android.com/reference/android/webkit/WebChromeClient.html

Page 25: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Example  between  WebViewClient  and  WebChromeClient

25

Page 26: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Handling  Links• Default  behavior:  load  that  URL  of  the  link  in  the  default  

Android  browser.  

26

Intercept  the  url  !!

Page 27: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Intercep6ng  WebView  HTTP  Requests• public  boolean  shouldOverrideUrlLoading  (WebView  view,  

String  url)  – Give  the  host  applica6on  a  chance  to  take  over  the  control  when  a  

new  url  is  about  to  be  loaded  in  the  current  WebView.  

27

Page 28: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Intercep6ng  example  1

28

if  (path.contains(ECWebView.WEB_URL_ECAUCTION_TYPE_PRODUCT_ITEM))  {                          showItemPage(url);  //  call  na6ve  component                          return  true;  }  

if  (path.contains(ECWebView.WEB_URL_ECAUCTION_TYPE_SELLER_BOOTH))  {                          showSellerBooth(url);  //  call  na6ve  component                          return  true;  }

Page 29: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Intercep6ng  example  2

29

if (whiteList.indexOf(host) != -1) { toggleLoadingUI(true); return false; }

Page 30: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

From  JavaScript  to  Java  -­‐  Android  Part

30

public  class  WebAppInterface  {          Context  mContext;  

       /**  Instan6ate  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();          }  }

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

Page 31: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

From  JavaScript  to  Java  -­‐  HTML  Part

31

<input  type="buWon"  value="Say  hello"  onClick="showAndroidToast('Hello  Android!')"  />  

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

Page 32: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

From  Java  to  JavaScript

32

mWebView.loadUrl("javascript:window.cartList.closeOverlay()");

Page 33: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Naviga6ng  web  page  history

33

@Override  public  boolean  onKeyDown(int  keyCode,  KeyEvent  event)  {          //  Check  if  the  key  event  was  the  Back  buWon  and  if  there's  history          if  ((keyCode  ==  KeyEvent.KEYCODE_BACK)  &&  myWebView.canGoBack())  {                  myWebView.goBack();                  return  true;          }          //  If  it  wasn't  the  Back  key  or  there's  no  web  page  history,  bubble  up  to  the  default          //  system  behavior  (probably  exit  the  ac6vity)          return  super.onKeyDown(keyCode,  event);  }

Page 34: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Cache  Web  Resources

34

@Override  public  WebResourceResponse  shouldInterceptRequest(WebView  view,  String  url)  {  

       if(url.startsWith("hWp://mydomain.com/ar6cle/")  {                  String  cacheFileName  =  url.substring(url.lastIndexOf("/"),  url.length());                  this.urlCache.register(url,  cacheFileName,                                  "text/html",  "UTF-­‐8",  60  *  UrlCache.ONE_MINUTE);          }  

       return  this.urlCache.load(url);  }  

Page 35: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Android  Lollipop• Mixed  content  issue

35

               if  (android.os.Build.VERSION.SDK_INT  >=  21)  {                          webSepngs.setMixedContentMode(WebSe<ngs.MIXED_CONTENT_ALWAYS_ALLOW);                  }

Page 36: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Cookie• CookieManager  

– Manages  the  cookies  used  by  an  applica6on's  WebView  instances.  • setCookie(String  url,  String  value)  • getCookie(url)  

• CookieSyncManager  – This  class  was  deprecated  in  API  level  21.  The  WebView  now  

automa6cally  syncs  cookies  as  necessary.  You  no  longer  need  to  create  or  use  the  CookieSyncManager.  To  manually  force  a  sync  you  can  use  the  CookieManager  method  flush()  which  is  a  synchronous  replacement  for  sync().  

36

Page 37: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Handle  HWp  Error

37

                       @Override                          public  void  onReceivedError(WebView  view,  int  errorCode,  String  descrip6on,  String  failingUrl)  {                                  …                          }  

                       @Override                          public  void  onReceivedSslError(WebView  view,  SslErrorHandler  handler,  SslError  error)  {                                  handler.proceed();  //  Ignore  SSL  cer6ficate  errors                          }

Page 38: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Handle  HWp  Error  bug• onReceivedError  STILL  does  not  receive  HTTP  Errors  

– hWps://code.google.com/p/android/issues/detail?id=82069

38

@Overridepublic void onPageFinished(WebView view, String url) {

if (WEBPAGE_ERROR_HTML_TITLE.indexOf(mWebContentTitle) != -1) { mListener.onPageReceivedError(view, WEBPAGE_ERROR_CODE, mWebContentTitle, url); }

}

Page 39: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Debugging  webview• Requirements  

– Chrome  32  or  later  installed  on  your  development  machine.  – A  USB  cable  to  connect  your  Android  device.  – For  app  debugging:  Android  4.4+  and  a  WebView  configured  for  

debugging.

39

 if  (Build.VERSION.SDK_INT  >=  Build.VERSION_CODES.KITKAT)  {              WebView.setWebContentsDebuggingEnabled(true);      }

Page 40: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Debugging  webview  cont.• The  chrome://inspect  page  displays  a  list  of  debug-­‐

enabled  WebViews  on  your  device.  • To  start  debugging,  click  inspect  below  the  WebView  you  

want  to  debug.    • As  of  KitKat  4.4.3,  screencast  is  available  for  both  browser  

tabs  and  Android  WebViews.

40

Page 41: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Tes6ng  with  Webview• Robo6um  

– hWps://code.google.com/p/robo6um/

41

               //  Type  in  text  box                  WebElement  txtSearch  =  solo.getWebElement(By.name("q"),  0);                  txtSearch.setTextContent("Hello");  

               //  click  buWon                  WebElement  btnSearch  =  (WebElement)  solo.getWebElement(By.name("btnG"),  0);                  solo.clickOnWebElement(btnSearch);

Page 42: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Project  that  Improve  Webview• Crosswalk  

– hWps://crosswalk-­‐project.org/  – Develop  around  device  fragmenta6on  – Provide  a  feature  rich  experience                                                                                                                          

all  on  Android  4.x  devices  – Easily  debug  with  Chrome  DevTools  – Improve  the  performance  of                                                                                                                                      

HTML,  CSS,  and  JavaScript

42

Page 43: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Conclusion• 這不是⾮非⿊黑即⽩白的世界  

– Web  跟  Na6ve  App  亦然  

• 讓  Web  和  Na6ve  App  共舞  – 提供使⽤用者最好的體驗

43

Page 44: When Web meet Native App

CONFIDENTIAL & PROPRIETARY

Thank  you

44

Eric  Chuang

hKp://bit.ly/1JkyR1W