分享

Android WebView在API17后addJavascriptInterface方法无效

 wusiqi111 2019-07-08

https://blog.csdn.net/u012721519/article/details/79173377

Webview是Android平台中一个重要组件,通常是通过在Activity中嵌套一个简单浏览器,实现在线网页浏览的功能或者实现Android与JavaScript的通信,此时addJavascriptInterface方法就显得尤为重要。但熟悉的人应该会有所发现,在API 17以后,addJavascriptInterface方法就失效了,下面将详细的介绍addJavascriptInterface方法以及失效解决方法。

一、 addJavascriptInterface简介

addJavascriptInterface是WebKit的原生API,属于WebView对象的公共方法,用于暴露一个java对象给js,使得js可以直接调用方法。当然,java与js的相互调用也离不开loadUrl()方法的配合使用。但是addJavascriptInterface的使用也是有些问题,因为Android平台封装WebKit内核时,不同的版本中会有些不一致。

二、网页内容

1. HTML代码

  1. <html>

  2. <head>

  3. <meta charset="gb-2312">

  4. <title>无标题文档</title>

  5. <link href="http://code./mobile/1.0/jquery.mobile-1.0.min.css" rel="stylesheet" type="text/css">

  6. <script src="http://code./jquery-1.6.4.min.js" type="text/javascript"></script>

  7. <script src="http://code./mobile/1.0/jquery.mobile-1.0.min.js" type="text/javascript"></script>

  8. </head>

  9. <body>

  10. <div data-role="page" id="page">

  11. <div data-role="header">

  12. <h1>标题</h1>

  13. </div>

  14. <div data-role="content">

  15. <ul data-role="listview" data-inset="true">

  16. <li data-role="list-divider">

  17. 注册

  18. </li>

  19. <li>

  20. <div data-role="fieldcontain">

  21. <label for="username">用户名:</label>

  22. <input type="text" name="textinput" id="username" value="张三" />

  23. </div></li><li>

  24. <div data-role="fieldcontain">

  25. <label for="password">密码:</label>

  26. <input type="password" name="textinput" id="password" value="zhangsan" />

  27. </div></li><li>

  28. <div data-role="fieldcontain">

  29. <fieldset data-role="controlgroup" data-type="horizontal">

  30. <legend>性别:</legend>

  31. <input type="radio" name="radio1" id="man" value="0" />

  32. <label for="man"></label>

  33. <input type="radio" name="radio1" id="woman" value="1" />

  34. <label for="woman"></label>

  35. </fieldset>

  36. </div></li><li>

  37. <div data-role="fieldcontain">

  38. <fieldset data-role="controlgroup" data-type="horizontal">

  39. <legend>爱好</legend>

  40. <input type="checkbox" name="checkbox1" id="football" class="custom" value="0" />

  41. <label for="football">足球</label>

  42. <input type="checkbox" name="checkbox1" id="basketball" class="custom" value="1" />

  43. <label for="basketball">篮球</label>

  44. <input type="checkbox" name="checkbox1" id="vollyball" class="custom" value="2" />

  45. <label for="vollyball">排球</label>

  46. </fieldset>

  47. </div>

  48. </li>

  49. <li>

  50. <div data-role="fieldcontain">

  51. <label for="selectmenu" class="select">国籍:</label>

  52. <select name="selectmenu" id="selectmenu">

  53. <option value="China">中国</option>

  54. <option value="America">美国</option>

  55. <option value="Japan">日本</option>

  56. </select>

  57. </div>

  58. </li>

  59. <li>

  60. <button id="commit">提交</button>

  61. </li>

  62. </ul>

  63. </div>

  64. <div data-role="footer" data-position="fixed">

  65. <h4>脚注</h4>

  66. </div>

  67. </div>

  68. </body>

  69. </html>

2.JS代码

  1. <script>

  2. $(function(){

  3. $("#commit").click(function(){

  4. var result = "{";

  5. result +="\"username\":\"";

  6. result +=$("#username").val();

  7. result +="\",\"password\":\"";

  8. result +=$("#password").val();

  9. result += "\",\"gender\":\"";

  10. result += $('input[name="radio1"]:checked').val();

  11. result += "\",\"interest\":\"";

  12. $('input[name="checkbox1"]:checked').each(function() {

  13. result += $(this).val()+",";

  14. });

  15. result += "\",\"country\":\"";

  16. result += $("#selectmenu option:selected").text()+"\"}";

  17. register_js.register(result);

  18. });

  19. });

  20. </script>

3.实现效果图

 

三、API 17以前addJavascriptInterface的使用方法

1.获取网页

  1. wv = (WebView) this.findViewById(R.id.wv1);

  2. wv.getSettings().setJavaScriptEnabled(true);

  3. wv.loadUrl("file:///android_asset/index.html");

  4. wv.addJavascriptInterface(new JSInterface(), "register_js")

register_js为交互时相互定义的名字。

2.JS中调用方法在Android中响应

  1. public void register(String userInfo){

  2. Toast.makeText(MainActivity.this, userInfo, Toast.LENGTH_LONG).show();

  3. }

register方法为js中调用的方法名,与addJavascriptInterface相对应。具体可参照JavaScript的代码。

四、API 17以后addJavascriptInterface的使用方法

1. 获取网页

  1. wv = (WebView) this.findViewById(R.id.wv1);

  2. wv.getSettings().setJavaScriptEnabled(true);

  3. wv.loadUrl("file:///android_asset/index.html");

  4. wv.addJavascriptInterface(new JSInterface(), "register_js")

2.JS中调用方法在Android中响应

  1. public void register(String userInfo){

  2. Toast.makeText(MainActivity.this, userInfo, Toast.LENGTH_LONG).show();

  3. }

3.注意

需要添加注解,否则addJavascriptInterface方法会失效。

  1. @SuppressLint("JavascriptInterface")

  2. @JavascriptInterface

4.方法更换原因

Android4.2以前WebView 提供了javascript 调用Java代码的方法,会造成很大的安全漏洞。Android官方在API 17后,限制javascript代码只能调用声明了@JavascriptInterface 注解的Java方法。

所以必须要给每个可供js代码调用的Java方法加一个@JavascriptInterface接口。

五、MainActivity.java代码

  1. package com.example.administrator.addjavascriptinterfacefunctiontest;

  2. import android.annotation.SuppressLint;

  3. import android.app.Activity;

  4. import android.content.Intent;

  5. import android.support.v7.app.AppCompatActivity;

  6. import android.os.Bundle;

  7. import android.webkit.JavascriptInterface;

  8. import android.webkit.WebView;

  9. import android.widget.Toast;

  10. public class MainActivity extends Activity {

  11. private WebView wv;

  12. @SuppressLint("JavascriptInterface")

  13. @Override

  14. protected void onCreate(Bundle savedInstanceState) {

  15. super.onCreate(savedInstanceState);

  16. setContentView(R.layout.activity_main);

  17. wv = (WebView) this.findViewById(R.id.wv1);

  18. wv.getSettings().setJavaScriptEnabled(true);

  19. wv.loadUrl("file:///android_asset/index.html");

  20. wv.addJavascriptInterface(new JSInterface(), "register_js");

  21. }

  22. private final class JSInterface{

  23. @SuppressLint("JavascriptInterface")

  24. @JavascriptInterface

  25. public void register(String userInfo){

  26. Toast.makeText(MainActivity.this, userInfo, Toast.LENGTH_LONG).show();

  27. }

  28. }

  29. }

六、源码下载

地址:http://download.csdn.net/download/u012721519/10225784

Good luck!

Write by Jimmy.li

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多