热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

WebView与JavaScript交互的四种形式

2019独角兽企业重金招聘Python工程师标准WebView如果作为简单的网页浏览器,对于一般的浏览行为来说,已经足够了。可做为企业开发者&#x

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

WebView如果作为简单的网页浏览器,对于一般的浏览行为来说,已经足够了。可做为企业开发者,你的App通常要嵌入自家公司的网页,如此一来,还得考虑App与Web之间的消息传递,这就涉及到App的原生代码与Web的JS代码之间的通信了。
App与Web做为消息通信的双方,具体的交互行为分为四类,包括:App通知Web执行某项动作、App主动从Web获取信息、Web通知App执行某项动作,Web主动从App获取信息,这四种行为详细说明如下:

1. App通知Web执行某项动作

Web提供一个Javascript方法,然后App由WebView调用loadUrl加载该JS方法,具体的App代码如下所示:

        wv_js.loadUrl("Javascript:showMsgFromWeb()");

该行为的执行效果如下图所示,App通知JS调用showMsgFromWeb方法,该方法弹出了一个alert消息框。

2. App主动从Web获取信息

WebView对象调用evaluateJavascript方法,该方法通过回调接口ValueCallback获得JS的返回串,具体的App代码如下所示:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// evaluateJavascript该方法为4.4以后引入wv_js.evaluateJavascript("getMsgFromWeb()", new ValueCallback() {@Overridepublic void onReceiveValue(String value) {AlertDialog.Builder builder = new AlertDialog.Builder(WebScriptActivity.this);builder.setTitle("来自安卓的对话框").setMessage(UnicodeToString(value));builder.create().show();}});} else {Toast.makeText(this, " Android4.4之后才支持该功能", Toast.LENGTH_SHORT).show();}

该行为的执行效果如下图所示,App通知JS调用getMsgFromWeb方法,获得返回消息后再由App自行弹窗。

3. Web通知App执行某项动作

App需要定义一个专门给JS使用的类,并在该类中实现JS要调用的方法,具体的类代码如下所示:

    private final class Client {@JavascriptInterfacepublic void showMsgFromAndroid(String msg) {  //如要返回值可把void改为String等等类型AlertDialog.Builder builder = new AlertDialog.Builder(WebScriptActivity.this);builder.setTitle("来自安卓的对话框").setMessage(msg);builder.create().show();}@JavascriptInterfacepublic String getMsgFromAndroid(String msg) {return "这是Android返回的字符串:"+msg;}}

接着还要调用WebView对象的addJavascriptInterface方法,给这个新类注册一个实例名,然后JS才能通过该实例名调用App的方法。注册实例名的代码如下所示:

        wv_js.addJavascriptInterface(new Client(), "client");

该行为的执行效果如下图所示,Web调用App的showMsgFromAndroid方法,该方法弹出了一个AlertDialog。

4. Web主动从App获取信息

该行为的主要流程同行为三,区别在于App方法的返回值类型由void改为String,然后JS即可从App获得返回信息。
该行为的执行效果如下图所示,Web调用App的getMsgFromAndroid方法获得字符串,然后Web把该消息以alert方式弹窗。

下面是演示WebView与Javascript交互用到的html文件源码:








测试js使用







为了区分对话框是App来源的弹窗还是Web来源的弹窗,这里重写了WebChromeClient的onJsAlert方法,通过setTitle方法区分本次弹窗的来源途径。重写后的方法代码如下所示:

        public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {String title &#61; mTitle;if (title&#61;&#61;null || title.length()<&#61;0) {title &#61; "来自网页的对话框";}AlertDialog.Builder builder &#61; new AlertDialog.Builder(WebScriptActivity.this).setTitle(title).setMessage(message).setPositiveButton("确定",new DialogInterface.OnClickListener() {&#64;Overridepublic void onClick(DialogInterface dialog, int which) {result.confirm();}});//setCancelable要设置为false&#xff0c;点击对话框外部时不让关闭对话框//不然JsResult的confirm方法没有得到执行&#xff0c;网页上的其它控件就不可使用builder.setCancelable(false).create().show();return true;}


另外还需注意WebView与Javascript相互调用的几个要点&#xff1a;
1. WebView要调用setWebChromeClient方法设置JS的解释客户端&#xff0c;从而避免JS中alert方法不弹窗的问题&#xff0c;因为JS页面的渲染需要WebChromeClient去实现。
2. 如果JS调用App代码时报错“Uncaught TypeError: Object [object Object] has no method”&#xff0c;那是因为Android4.2以上版本默认不开放JS调用本地方法的权限&#xff0c;得给开放JS调用的方法加上“&#64;JavascriptInterface”注释&#xff0c;该注释允许JS代码访问APP的指定方法。
3. evaluateJavascript是Android在4.4.2之后才引入的新方法&#xff0c;如果是4.4.2之前的Android版本&#xff0c;需要注意做兼容处理。
4. JS调用App方法&#xff0c;返回值中的中文是正常&#xff1b;但App获取JS方法&#xff0c;返回值的中文却是“\u”打头的字符串&#xff0c;所以要先将JS返回的字符串做转义处理&#xff0c;转义后的字符串才是App能够处理的正常汉字。
5. 如果App与JS存在嵌套调用&#xff08;即A调用B&#xff0c;B内部又去调用A&#xff09;&#xff0c;那么Android4.4.2之后务必要保证两个调用在同一个线程中&#xff0c;不然运行时会报错“java.lang.Throwable: A WebView method was called on thread &#39;JavaBridge&#39;. All WebView methods must be called on the same thread.”。具体的解决方法是&#xff1a;调用WebView对象的post方法&#xff0c;然后在post的Runnable任务中再去调用JS方法&#xff0c;例子代码如下所示&#xff1a;

    private final class Contact {//网页的JS调用App的showcontacts方法&#xff0c;然后showcontacts内部又去调用JS的show方法&#64;JavascriptInterfacepublic void showcontacts() {wv_local.post(new Runnable() {&#64;Overridepublic void run() {wv_local.loadUrl("Javascript:show()");}});}}

 


转:https://my.oschina.net/ouysh1981/blog/1608923



推荐阅读
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • intellij idea的安装与使用(保姆级教程)
    intellijidea的安装与使用(保姆级教程)IntelliJ在业界被公认为最好的java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(gi ... [详细]
author-avatar
尼姆了_960
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有