• android + javascript 相互通信实例分析


    1.  AndroidManifest.xml中必须使用许可 "android.permission.INTERNET", 否则会出Web page not available错误。

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

    2.  如果访问的页面中有Javascript,则webview必须设置支持Javascript。

    1   WebSettings webSetting = webview.getSettings();
    2   webSetting.setJavaScriptEnabled(true);

    3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象或者覆盖webview的 setWebChromeClient

    1 mWebView.setWebViewClient(new WebViewClient(){
    2 public boolean shouldOverrideUrlLoading(WebView view, String url) { 
    3     view.loadUrl(url); 
    4     return true; 
    5    } 6 });
     1   mWebView.setWebChromeClient(new MyWebChromeClient()
     2             @Override
     3             public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
     4                 Log.d(LOG_TAG, message);
     5                 result.confirm();
     6                 return true;
    7             });

    4.  如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网 页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。

    1 public boolean onKeyDown(int keyCode, KeyEvent event) { 
    2   if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { 
    3     mWebView.goBack(); 
    4     return true; 
    5   } 
    6   return super.onKeyDown(keyCode, event); 
    7 } 

     5.  javascript对象 与 android 对象绑定

    WebView注入Java对象

      对象注入即通过webview 建立 javascript对象 与 android 原生对象的绑定关系,下面代码中,obj1对象在android程序中可以操作,obj2在js程序中可以操作,两者操作的均为同一个内存对象,即可以理解为,两个绑定的对象是同一个对象在不同运行环境下的一个别名(仅个人理解,有误请大牛指正)

    1 webview.getSetting().setJavaScriptEnable(true);  
    2 class JsObject {  
    3     @JavascriptInterface  
    4     public String toString() { return "injectedObject"; }  
    5  }  
    6  webView.addJavascriptInterface(new JsObject()obj1, "injectedObject"obj2);  

      上面的程序建立 javascript 与android 程序的绑定关系,android 4.2 之后版本提供给js调用的函数必须带有注释语句@JavascriptInterface ,4.2版本之前向webview注入的对象所暴露的接口不是必须带有@JavascriptInterface注释语句(需要注意,android adt,eclipse生成的工程,低版本中会自动带有 anotations.jar,支持@JavascriptInterface, 而高版本中工程中,不会自动带有anotations.jar包,所以要加入注释语句@JavascriptInterface,首先要自己手动加入anotations.jar包,不要忘记import 哦!本人就犯过这么低级的错误哦)

       官方文档解释是因为这个接口允许JavaScript 控制宿主应用程序,这是个很强大的特性,但同时,在4.2的版本前存在重大安全隐患,因为JavaScript 可以使用反射访问注入webview的java对象的public fields,在一个包含不信任内容的WebView中使用这个方法,会允许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。因此4.2以后,任何为JS暴露的接口,都需要加 @JavascriptInterface 注释,这样,这个Java对象的fields 将不允许被JS访问。[2] 

       注:如果将targetSdkVersion 设置为17或者更高,但却没有给暴露的js接口加@JavascriptInterface注释,则logcat会报如下输出:

       Console: Uncaught TypeError: Object [object Object] has no method 'toString'

      (需要特注意的一点,这里的限制是通过 targetSdkVersion 为标准,即如果工程采用了android sdk的版本是4.2以上,但是 targetSdkVersion 的版本在17之下,那么该状态下生成的应用,不过报错,如果targetSdkVersion 设置为>=17 就需要特别主意,要加上 @JavascriptInterface注释语句了, 所有建议在各种版本下都采用@JavascriptInterface注释,就万无一失了)

    6.  在做webview开发是经常会加载本机的html文件如下:

     file:///android_asset/teste.html   加载项目assets下的文件teste.html

     file:///sdcard/index.html       加载sdcard下的index.html文件

    源代码:

    android

     1      private WebView mWebView;
     2       private Handler mHandler = new Handler();
     3       
     4       @Override
     5       protected void onCreate(Bundle savedInstanceState) {
     6           super.onCreate(savedInstanceState);
     7          setContentView(R.layout.main);
     8          mWebView = (WebView) findViewById(R.id.webview);
     9 
    10          WebSettings webSettings = mWebView.getSettings();
    11          webSettings.setJavaScriptEnabled(true);
    12          webSettings.setSavePassword(false);
    13          webSettings.setSaveFormData(false);
    14          webSettings.setSupportZoom(false);
    15  
    16          mWebView.setWebChromeClient(new MyWebChromeClient());
    17          mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
    18  //      mWebView.loadUrl("http://www.baidu.com/");
    19          mWebView.loadUrl("file:///android_asset/demo.html");
    20      }
    21      
    22       final class DemoJavaScriptInterface {
    23              DemoJavaScriptInterface() {
    24                  Log.i("aaaa", "create DemoJavaScriptInterface");
    25              }
    26              /**
    27               * This is not called on the UI thread. Post a runnable to invoke
    28               * loadUrl on the UI thread.
    29               */
    30         @JavascriptInterface
    31              public void clickOnAndroid() {
    32                 mHandler.post(new Runnable() {
    33                     public void run() {
    34                          mWebView.loadUrl("javascript:wave()");
    35                      }
    36                  });
    37              }
    38          }
    39          /**
    40          * Provides a hook for calling "alert" from javascript. Useful for
    41           * debugging your javascript.
    42           */
    43         final class MyWebChromeClient extends WebChromeClient {
    44             @Override
    45              public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
    46                 result.confirm();
    47                 return true;
    48             }
    49         }

    html源文件

     1 <!DOCTYPE html>
     2 <html>
     3     <script language="javascript">
     4         /* This function is invoked by the activity */
     5         function wave() {
     6             alert("1");
     7             document.getElementById("droid").src="android_waving.png";
     8             alert("2");
     9         }
    10     </script>
    11     <body>
    12         <!-- Calls into the javascript interface for the activity -->
    13         <a onClick="window.demo.clickOnAndroid()">
    14         <div style="80px;
    15             margin:0px auto;
    16             padding:10px;
    17             text-align:center;
    18             border:2px solid #202020;" >
    19                 <img id="droid" src="android_normal.png"/><br>
    20                 Click me!
    21         </div></a>
    22     </body>
    23 </html>

    参考文档:

    [1]. WebView注入Java对象注意事项     参考:http://blog.csdn.net/zgjxwl/article/details/9627685

    [2]. Android WebView的Js对象注入漏洞解决方案  http://my.oschina.net/u/1402271/blog/306364

    [3]. https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface

    [4]. http://wenku.baidu.com/link?url=MLiRIwZQUc3-CAbSopUD-_OZ2Jt67K74RHDzqVJZCkDRnbkXp-66P9ArMbtNSy3LiPZ__nLxcQaoXP7ZImv7AujsFwBybB9wlbCJaGVTjD_

    [5]. https://code.google.com/p/apps-for-android/source/browse/#git%2FSamples%2FWebViewDemo%253Fstate%253Dclosed

  • 相关阅读:
    BZOJ2565:最长双回文串
    BZOJ2342:[SHOI2011]双倍回文
    Redis数据库基础操作
    Celery异步任务框架
    Django框架之缓存数据库
    drf 分页器组件
    drf jwt认证组件
    drf三大认证组件
    Django框架之RBAC+ContentType
    Django框架之admin管理后台
  • 原文地址:https://www.cnblogs.com/yaozhongxiao/p/3408948.html
Copyright © 2020-2023  润新知