整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

WebView与JavaScript的交互

WebView与JavaScript的交互

于现如今H5的热门,做过不少与H5的交互工作了,现在总结一下。

初始化WebView

/**

* 初始化WebView

*/

private void initWebView() { // 设置setWebChromeClient对象

mWb_main.setWebChromeClient(new WebChromeClient() { @Override

public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); //设置本地的ToolBar标题

mTv_main.setText(title);

}

});

. Qt使用类

1. QWebChannel

2. QWebEngineView


二. Qt JS文件

1. qwebchannel.js 一般在安装目录下 \webchannel\shared\qwebchannel.js


三. Qt代码

1. 定义交互类

#include <QWebEnginePage>

class JsClass: public QObject

{

Q_OBJECT

public:

explicit JsClass(QObject *parent=nullptr);

// qt 调用 js 函数

void qt_exec_js(QWebEnginePage* page, const QString& param) {

page->runJavaScript(QString("print_info(\"%1\")").arg(param)); //调用函数带字符串类型参数一定需要加双引号

//page->runJavaScript(QString("print_info(%1)").arg(12)); //调用函数参数类型为数字类型

//page->runJavaScript(QString("print_info()")); //调用函数无参

}

public slots:

// js 调用 qt 函数

void js_exec_qt(const QString& param) {

qDebug() << param;

}

};


2. 主函数代码片段

QString url="file:///E:/login.html";

QWebEngineView webView

webView.load(QUrl(url));

webView.show();


JsClass jsClass;

QWebChannel webChannel;

webChannel.registerObject("jsClass", &jsClass);

webView.page()->setWebChannel(&webChannel);


connect(&webView, &QWebEngineView::loadFinished, this, [](){ jsClass.qt_exec_js(webView.page(), "Hello word");});

//重要, 必须要等到 QWebEngineView 类把html加载完毕才能执行调用js的函数, 不然会出现找不到js函数的错误


四. HTML 和 JS 代码

<!DOCTYPE html>

<html>

<head>

</head>

<body>

<div id="demo"></div>

</body>

</html>


<script src="./qwebchannel.js"></script> //把Qt中提供的js加入进来


<script>

var jsClassIns;

// 获取qt中 JsClass 类的实例

function initObj(){

if (typeof qt !='undefined'){

new QWebChannel(qt.webChannelTransport, function(channel){

jsClassIns=channel.objects.jsClass; //名字和 webChannel.registerObject("jsClass", &jsClass); 第一个参数保持一致

});

}

}

// 调用Qt函数

function exec_qt(param){

if(typeof jsClassIns !='undefined'){

jsClassIns.js_exec_qt(param);

}

}

//Qt 调用 js

function print_info(param) {

document.getElementById("demo").innerHTML=param;

exec_qt("Hello China"); //当Qt调用了 js, Js 也调用Qt函数

}

initObj();

</script>

着移动端互联网的发展,越来越的APP运用到H5,可移动端H5与原生JavaScript是如何交互的呢?

JavaScript调用Native的方式,主要有两种:注入API和拦截URL SCHEME。

注入 API 方式

其主要原理是,通过WebView提供的接口,向JavaScript的Context(window)中注入对象或者方法,让JavaScript调用时,直接执行相应的Native代码逻辑,达到JavaScript调用Native的目的。

针对Android和IOS有不同的处理方式:

1、Android的处理方式

Android中,就是新建一个类,里面写提供给H5操作的方法,并规定别名。

在安卓4.2以上可以直接使用@JavascriptInterface注解来声明。

定义完这个方法后再调用mWebView.addJavascriptInterface()方法。

将方法注入在window中,H5调用时,根据“window. 别名.方法”来调用。

2、IOS的处理方式

IOS是利用WKWebView的新特性MessageHandler来实现JS调用原生方法的。

WKWebView初始化时,创建WKWebViewConfiguration对象,配置各个接口对应的MessageHandler,然后再接受js传递的参数调用接口。

H5中调用时,使用window.webkit.messageHandlers.接口名. postMessage(参数)。

拦截 URL SCHEME

拦截URL SCHEME的主要流程是:Web端通过某种方式(例如iframe.src)发送URL Scheme 请求,之后Native拦截到请求并根据URL SCHEME(包括所带的参数)进行相关操作。

在这个过程中,这种方式有一定的缺陷:

  • 使用iframe.src发送URL SCHEME会有URL长度的隐患,而且特殊字符需要编码解码。
  • 创建请求,需要一定的耗时,比注入API的方式调用同样的功能,耗时会较长。