博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 与 WebView 数据交互
阅读量:6526 次
发布时间:2019-06-24

本文共 4392 字,大约阅读时间需要 14 分钟。

1. 创建Android 项目

    1. 打开Android Studio

-w450

    1. 创建一个空的Android项目

-w450

    1. 打开Android虚拟机,这里使用的是Genymotion

15268784107324.jpg

2. 添加webview

    1. 清空layout内容,添加WebView控件
    1. MainActivity中创建引入webview
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    WebView mweb = findViewById(R.id.web);    mweb.loadUrl("http://www.baidu.com");}
    1. 此时运行项目,发现android安装成功,webview也可以打开,但是页面请求失败,需要给APP添加联网权限。
      AndroidManifest.xmlmanifest标签内添加
    1. 此时运行项目,发现webview可以打开并且百度页面可以访问了,但是仔细发现webview并不是在自己的APP上打开的,而是弹出系统浏览器。因为webview只是载体,内容的渲染需要使用webviewChromClient类去实现此时需要setWebViewClient
...WebView mweb = findViewById(R.id.web);mweb.setWebViewClient(new WebViewClient());mweb.loadUrl("http://www.baidu.com");...
    1. 运行APP后可以看到webview已经差不多是我们想要的了

15268792310451.jpg

3. 设置JavaScript可执行

仔细看会发现,通过上面步骤打开的百度首页跟我们平时看到的广告页面不一样,原因是WebView默认禁止了JS的执行。这也是我觉得百度首页做的比较好的地方,在无JS环境下仍可提供服务。

  • 添加setJavaScriptEnabled
...mweb.setWebViewClient(new WebViewClient());mweb.getSettings().setJavaScriptEnabled(true);mweb.loadUrl("http://www.baidu.com");...

此时再打开页面,就会发现广告出来了,并且页面很卡。

15268796309520.jpg

4. WebView 调用 Android 方法

1. 使用addJavascriptInterface

    1. 添加JS接口
      创建JavaScriptInterFace.java类,用来写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函数。

    1. addJavascriptInterface注入
...mweb.setWebViewClient(new WebViewClient());mweb.getSettings().setJavaScriptEnabled(true);mweb.addJavascriptInterface(new JavaScriptInterFace(), "JSBridge"); // JSBridge 为 webview 中调用的对象名称mweb.loadUrl("http://www.baidu.com");...
    1. 加载本地 html 文件

app/src/main目录下面创建目录assets并新建a.html文件,写入如下代码

                

123

修改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
() { @Override public void onReceiveValue(String value) { Log.d("tagee", value); }});

4. 通过shouldOverrideUrlLoading()

shouldOverrideUrlLoadingWebViewClient对象的一个"生命周期",用拦截URL的请求,监听网页地址的变化,返回turefalse来决定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&param2=asd"        Uri uri = Uri.parse(url);        if ( uri.getScheme().equals("js")) {            //可以在此处获取页面请求数据并处理            //或则直接跳转activity等            return true;        }        return false;    }}

值得一提的是以前一直有一个误区,以为使用一个不可见的iframe标签,再动态改变其src也可以捕捉url变化达到传值的目的。测试过不可行,包括默认写入和动态创建iframe

4. 通过onJsAlert()、onJsConfirm()、onJsPrompt()

原理和上面一条一样,通过监听页面的弹窗事件,达到传值的目的,不细说了。

转载地址:http://nxnbo.baihongyu.com/

你可能感兴趣的文章
《Effective C#》读书笔记——条目1:使用属性而不是可访问的数据成员<C#语言习惯>...
查看>>
转】matlab 字符串处理函数
查看>>
oc66--代理模式应用2
查看>>
JSONObject和JSONArray(json-lib-2.4)的基本用法
查看>>
隐藏在程序旮旯中的“安全问题”
查看>>
attachEvent传递给其handler的一个默认参数
查看>>
架构与安全(Schemas and Security)
查看>>
Ajax跨域访问XML数据的另一种方式——使用YQL查询语句
查看>>
[原创]让您的服务器不再有被挂马的烦恼---文件安全卫士
查看>>
Boot loader startup sequence
查看>>
Gitlab-ci与RUNNER的安装与使用
查看>>
江西打造千亿级移动物联网产业
查看>>
开始云私有云存储系统:让数据更安全高效
查看>>
Qt for S60 安装
查看>>
美国往事 - 追忆我的房东Dick 最终篇 - 伤感的结局
查看>>
【网络资料整理】-【redis】面试题目
查看>>
vue--角色管理
查看>>
Python 中的设计模式详解之:策略模式
查看>>
webpack+vue+typescript项目配置
查看>>
java源码学习-Spliterator
查看>>