Android 与 WebView 数据交互

简介:

1. 创建Android 项目

    1. 打开Android Studio

-w450

    1. 创建一个空的Android项目

-w450

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

15268784107324.jpg

2. 添加webview

    1. 清空layout内容,添加WebView控件
<WebView
        android:id="@+id/web"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    1. 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");
}
    1. 此时运行项目,发现android安装成功,webview也可以打开,但是页面请求失败,需要给APP添加联网权限。
      AndroidManifest.xmlmanifest标签内添加
<uses-permission android:name="android.permission.INTERNET"/>
    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文件,写入如下代码

<!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()

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()

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

目录
相关文章
|
4天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
5 0
|
4天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
5 0
|
17天前
|
XML Java Android开发
Android每点击一次按钮就添加一条数据
Android每点击一次按钮就添加一条数据
21 1
|
1月前
|
移动开发 JavaScript Android开发
Android与Html5交互
Android与Html5交互
|
1月前
|
存储 Android开发 C++
【Android 从入门到出门】第五章:使用DataStore存储数据和测试
【Android 从入门到出门】第五章:使用DataStore存储数据和测试
30 3
|
2月前
|
JavaScript Java 数据安全/隐私保护
安卓逆向 -- POST数据解密
安卓逆向 -- POST数据解密
25 2
|
2月前
|
XML Android开发 数据格式
安卓和webview交互
安卓和webview交互
25 0
|
3月前
|
编解码 测试技术 开发工具
如何实现Android视音频数据对接到GB28181平台(SmartGBD)
如何实现Android视音频数据对接到GB28181平台(SmartGBD)
|
21天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
12天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。