Android 与 WebView 数据交互
1. 创建Android 项目
-
- 打开Android Studio
-
- 创建一个空的Android项目
-
- 打开Android虚拟机,这里使用的是Genymotion
2. 添加webview
-
- 清空layout内容,添加WebView控件
<WebView android:id="@+id/web" android:layout_width="match_parent" android:layout_height="match_parent"/>
-
- 在
MainActivity
中创建引入webview
- 在
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WebView mweb = findViewById(R.id.web); mweb.loadUrl("http://www.baidu.com"); }
-
- 此时运行项目,发现android安装成功,webview也可以打开,但是页面请求失败,需要给APP添加联网权限。
在AndroidManifest.xml
的manifest
标签内添加
- 此时运行项目,发现android安装成功,webview也可以打开,但是页面请求失败,需要给APP添加联网权限。
<uses-permission android:name="android.permission.INTERNET"/>
-
- 此时运行项目,发现webview可以打开并且百度页面可以访问了,但是仔细发现webview并不是在自己的APP上打开的,而是弹出系统浏览器。因为webview只是载体,内容的渲染需要使用webviewChromClient类去实现此时需要
setWebViewClient
- 此时运行项目,发现webview可以打开并且百度页面可以访问了,但是仔细发现webview并不是在自己的APP上打开的,而是弹出系统浏览器。因为webview只是载体,内容的渲染需要使用webviewChromClient类去实现此时需要
... WebView mweb = findViewById(R.id.web); mweb.setWebViewClient(new WebViewClient()); mweb.loadUrl("http://www.baidu.com"); ...
-
- 运行APP后可以看到webview已经差不多是我们想要的了
3. 设置JavaScript可执行
仔细看会发现,通过上面步骤打开的百度首页跟我们平时看到的广告页面不一样,原因是WebView默认禁止了JS的执行。这也是我觉得百度首页做的比较好的地方,在无JS环境下仍可提供服务。
- 添加
setJavaScriptEnabled
... mweb.setWebViewClient(new WebViewClient()); mweb.getSettings().setJavaScriptEnabled(true); mweb.loadUrl("http://www.baidu.com"); ...
此时再打开页面,就会发现广告出来了,并且页面很卡。
4. WebView 调用 Android 方法
1. 使用addJavascriptInterface
-
- 添加JS接口
创建JavaScriptInterFace.java
类,用来写JS调用方法
- 添加JS接口
package com.test.myapplication; import android.util.Log; import android.webkit.JavascriptInterface; public class JavaScriptInterFace { @JavascriptInterface public String getValue(String name) { Log.d("tagee", "getValue:" + name); return "call back"; } }
因为安全问题,在Android4.2中JS只能访问带有 @JavascriptInterface
注解的Java函数。
-
- addJavascriptInterface注入
... mweb.setWebViewClient(new WebViewClient()); mweb.getSettings().setJavaScriptEnabled(true); mweb.addJavascriptInterface(new JavaScriptInterFace(), "JSBridge"); // JSBridge 为 webview 中调用的对象名称 mweb.loadUrl("http://www.baidu.com"); ...
-
- 加载本地 html 文件
在app/src/main
目录下面创建目录assets
并新建a.html
文件,写入如下代码
<!doctype html> <html lang="en"> <head></head> <body> <h1 id="h1">123</h1> <script> if(window.JSBridge){ alert(JSBridge.getValue('from JS')); } </script> </body> </html>
修改webview的loadUrl
参数
mweb.addJavascriptInterface(new JavaScriptInterFace(), "JSBridge"); mweb.loadUrl("file:///android_asset/a.html");
此时重新build,可以看到Logcat
打印出from JS
,并且页面弹窗。
2.通过loadUrl()
loadUrl
可以执行JavaScript代码,他有如下特征:
1. 调用`loadUrl`会刷新页面 2. 当参数为要执行的JS代码时,要有document对象,至少得load一个空白页,否则会失效 3. 若返回值为非空字符串,则会将返回值替换页面原本的内容 4. 可以调用html中的js代码,但需要在`onPageFinished`回调之后才能调用,并且注意第三点的影响,防止返回字符串替换文档
如:
... mweb.addJavascriptInterface(new JavaScriptInterFace(), "JSBridge"); mweb.loadUrl("javascript:aler(123)"); //因当前webview没用加载任何页面,脚本无效
... mweb.addJavascriptInterface(new JavaScriptInterFace(), "JSBridge"); mweb.loadUrl("file:///android_asset/a.html"); mweb.loadUrl("javascript:'123'"); //此时页面被替换成123
protected void onCreate(Bundle savedInstanceState) { ... mweb.addJavascriptInterface(new JavaScriptInterFace(), "JSBridge"); mweb.setWebViewClient(new mWebViewClient()); mweb.loadUrl("file:///android_asset/a.html"); } ... private class mWebViewClient extends WebViewClient{ @Override public void onPageFinished(WebView view, String url) { view.loadUrl("javascript:callJS()");//callJS为a.html中定义的方法 super.onPageFinished(view, url); } }
实际使用时,Android更多的是调用远程JS代码,即将加载的JS代码路径改成url即可。或则直接拼接JS代码时也会放在闭包中执行,防止替换页面内容。
3. 通过evaluateJavascript()
如果是Android4.4后,推荐使用evaluateJavascript
,比loadUrl
效率更高,并且不会刷新页面。evaluateJavascript
有两个参数,第一个为脚本内容,第二个则是脚本的执行结果。在onPageFinished
调用:
view.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { Log.d("tagee", value); } });
4. 通过shouldOverrideUrlLoading()
shouldOverrideUrlLoading
是WebViewClient
对象的一个"生命周期",用拦截URL的请求,监听网页地址的变化,返回ture
或false
来决定webview是否加载URL。
1. 若没有设置 WebViewClient 则由系统(Activity Manager)处理该 url,通常是使用浏览器打开或弹出浏览器选择对话框,即出现上文2.4的情况。 2. 若设置 WebViewClient 且该方法返回 true ,则说明由应用的代码处理该 url,WebView不跳转。 3. 若设置 WebViewClient 且该方法返回 false,则说明由 WebView 处理该 url,即用 WebView 加载该 url。
private class mWebViewClient extends WebViewClient{ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //此处可以解析url进行处理, //也可以直接调用view.loadUrl(url); 在当前的webview中跳转到新的url //若前端直接location.href="js://web?param1=123¶m2=asd" Uri uri = Uri.parse(url); if ( uri.getScheme().equals("js")) { //可以在此处获取页面请求数据并处理 //或则直接跳转activity等 return true; } return false; } }
值得一提的是以前一直有一个误区,以为使用一个不可见的iframe
标签,再动态改变其src
也可以捕捉url变化达到传值的目的。测试过不可行,包括默认写入和动态创建iframe
4. 通过onJsAlert()、onJsConfirm()、onJsPrompt()
原理和上面一条一样,通过监听页面的弹窗事件,达到传值的目的,不细说了。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
用mongols轻松打造websocket应用
用websocket做聊天系统是非常合适的。 mongols是一个运行于linux系统之上的开源c++库,可轻松开启一个websocket服务器。 首先,build一个websocket服务器。 #include <mongols/ws_server.hpp> //websocket server int main(int,char**){ int port=9090; const char* host="127.0.0.1"; mongols::ws_server server(host,port); server.run(); } 才几行,这就成了吗?没错!不信你用wsdump.py测试下。测了啊,怎么一发送消息就关闭了连接?这是因为该服务器只接受json字符串消息,并且规定了几个必要field.否则只能接收消息,一发送就将关闭连接: gid,默认0 uid,默认0 gfilter,默认空数组[],表示转发给任意gid用户,非空则只发送给特定gid用户 ufilter,默认空数组[],表示转发给任意uid用户,非空则只发送给特定uid用户 其他field为开发者自己决...
- 下一篇
成为Java顶尖程序员,先过了下面问题!
一、数据结构与算法基础 说一下几种常见的排序算法和分别的复杂度。 用Java写一个冒泡排序算法 描述一下链式存储结构。 如何遍历一棵二叉树? 倒排一个LinkedList。 用Java写一个递归遍历目录下面的所有文件。 二、Java基础 接口与抽象类的区别? Java中的异常有哪几类?分别怎么使用? 常用的集合类有哪些?比如List如何排序? ArrayList和LinkedList内部的实现大致是怎样的?他们之间的区别和优缺点? 内存溢出是怎么回事?请举一个例子? ==和equals的区别? hashCode方法的作用? NIO是什么?适用于何种场景? HashMap实现原理,如何保证HashMap的线程安全? JVM内存结构,为什么需要GC? NIO模型,select/epoll的区别,多路复用的原理 Java中一个字符占多少个字节,扩展再问int, long, double占多少字节 创建一个类的实例都有哪些办法? final/finally/finalize的区别? Session/Cookie的区别? String/StringBuffer/StringBuilder的区别,...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8编译安装MySQL8.0.19
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长