Cordova插件使用——Themeablebrowser数据花式交互

Themeablebrowser是一个外部浏览器插件,它fork自inappbrowser,相比于后者,此插件的目的是提供一个可以与你的应用程序的主题相匹配的in-app-browser,以便给你的应用保持一致的外观和感觉。所以,除了一些主题化的配置外,核心部分使用参考inappbrowser文档。

inappbrowser的方法有以下几个,通过它们实现js和插件的交互:

  • addEventListener
  • removeEventListener
  • close
  • show
  • hide
  • executeScript
  • insertCSS

而其中,又主要使用addEventListenerexecuteScript

-- addEventListener

使用方式如下:

ref.addEventListener(eventname, callback);

其中eventname,即事件名只有以下4个:

  • loadstart: 当InAppBrowser开始加载一个URL时抛出事件.
  • loadstop: 当InAppBrowser结束加载一个URL时抛出事件.
  • loaderror: 当InAppBrowser加载一个URL出现错误时抛出事件.
  • exit: 当InAppBrowser窗口关闭时抛出事件.

-- executeScript

使用方式如下:

ref.executeScript(details, callback);

其中details,是要运行的js脚本,可以指定文件或代码:

  • file: 要注入的js脚本的URL.
  • code: 要注入的js脚本文本.

从注入脚本和可用事件提供的信息来看,数据传输是单向的,与http协议无状态概念一致,也就是说一般使用仅是应用主动向浏览器插件发送数据,然后接收回调信息,然而,若想浏览器插件主动传递数据给应用,也不是不可以的!

准备工作(1)——准备供浏览器插件访问的网页

新建并发布一个网页,供浏览器插件访问。这里我简单用node搭建一个网页(由上往下分别是创建目录、跳过询问来配置package.json、安装express):

mkdir testWeb && cd testWeb
npm init -y
npm i express --save

新建index.js文件,并填入以下内容:

const express = require('express')
const path = require('path')
const app = express()

app.use(express.static(__dirname))
app.listen(8089, () => {
  console.log(`App listening at port 8089`)
})

这样就部署了个静态网页服务器,在testWeb目录下我们再创建一个html页面和一个js文件:
index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
  <title>父子组件参数传递测试</title>
</head>
<body>
  <h1>父子组件参数传递测试</h1>
  <button id="btnGet">接收参数</button>
  <button id="btnReturnByJump">基于跳转返回数据</button>
  <button id="btnReturnByDetect">基于检测返回数据</button>
  <script src="test.js"></script>
</body>
</html>

test.js:

var fromAppData = '';
var jumpData = '';   //跳转的返回数据
var detectData = '';    //检测的返回数据
var btnGet = document.getElementById("btnGet");
btnGet.onclick = function(){
    alert(JSON.stringify(fromAppData));
}

function sayHello(data){
    detectData = '';
    fromAppData = data;
    alert(data.text);
    return 'world';        //区分data.text,这里返回任意值
}

var btnReturnByJump = document.getElementById("btnReturnByJump");
btnReturnByJump.onclick = function(){
    jumpData = 'jump:' + new Date().getTime();
    window.open('close');
}
/**
 * 获取跳转返回的数据
 */
function getJumpData(){
    return jumpData;
}

var btnReturnByDetect = document.getElementById("btnReturnByDetect");
btnReturnByDetect.onclick = function(){
    detectData = 'detect:' + new Date().getTime();
    alert(detectData);
}

/**
 * 获取检测的数据
 */
function getDetectData(){
    return detectData;
}

执行命令启动:

node index.js

在浏览器访问一下是否能正常运行:http://localhost:8089,实际真机测试时换成IP访问:http://192.168.2.130:8089

准备工作(2)——安装插件

hybird应用执行命令安装插件:

cordova plugin add cordova-plugin-themeablebrowser

测试APP主动向插件发送数据,并获取返回。

在应用中添加调用插件接口:

 var ref = cordova.ThemeableBrowser.open('http://192.168.2.130:8089/index.html', '_blank', {
      closeButton: {
        image: 'close',
        imagePressed: 'close_pressed',
        align: 'left',
        event: 'closePressed'
      },  
      customButtons: [
        {
          image: 'share',
          imagePressed: 'share_pressed',
          align: 'right',
          event: 'sharePressed'
        }]
 })
.addEventListener('sharePressed', function (event) {
      ref.executeScript({ code: "getJumpData()" }, (params) => {
         console.log(JSON.stringify(params));
      });
});

 ref.addEventListener('loadstop', function (params) {
      //调用浏览器内部页面的js方法
      ref.executeScript({ code: "sayHello({text: 'hello'})" }, (params) => {
          console.log(params);
      });
});

在loadstop响应事件后注入js调用内部网页的方法sayHello,这样,在URL加载完成后就会执行该方法,为了测试json数据是否正常传递,浏览器内部页面的方法打印data.text,并返回“world”,结果如下图正确输出:

image.png

同时,点击浏览器页面的【接收参数】按钮,也是能正确打印出传递进来的fromAppData

测试插件主动向APP传送数据。

方法还是有不少的,现举三种方法抛砖引玉一下:

1. 页面跳转法
在APP里面添加下面事件监听的代码:

 ref.addEventListener('loadstart', (event) => {
      if (event.url.match("close")) {
        ref.executeScript({ code: "getJumpData();" }, (params) => {
          console.log(JSON.stringify(params));
          ref.close();
        });
      }
    });

观察下,在浏览器页面的test.js里面有以下内容:

var btnReturnByJump = document.getElementById("btnReturnByJump");
btnReturnByJump.onclick = function(){
    jumpData = 'jump:' + new Date().getTime();
    window.open('close');
}

上面的内容结合起来的意思是:【基于跳转返回数据】按钮点击后保存一个变量jumpData,然后调用window.open('close')实现跳转,此时会被loadstart事件监听到,再注入js脚本获取jumpData数据,在控制台是看到有如下正确输出的:

image.png

2. 轮询检测法
在当年没有用推送的老时代,轮询是一种常见但相对耗费性能的方法,在这里可以用一下。
在APP里面修改下面事件监听的代码:

 ref.addEventListener('loadstop', (event) => {
      ref.executeScript({ code: "sayHello({text: 'hello'})" }, (params) => {
        console.log(params);
      });
      //启动定时器
      var loop = setInterval(() => {
        ref.executeScript({ code: "getDetectData()" }, (params) => {
          var detectData = params[0];
          if (detectData) {
            console.log(detectData);
            //销毁定时器
            clearInterval(loop);
            ref.close();
          }
        }, 500);
      });
    });

再次观察下,在浏览器页面的test.js里面有以下内容:

var btnReturnByDetect = document.getElementById("btnReturnByDetect");
btnReturnByDetect.onclick = function(){
    detectData = 'detect:' + new Date().getTime();
    alert(detectData);
}

上面的内容结合起来的意思是:【基于检测返回数据】按钮点击后设置一个变量detectData,此时会被APP里面的轮询检测到detectData不为空时,就打印数据,并停止轮询,在浏览器也是能正常输出的。

3. 浏览器插件自定义原生按钮法
APP里面留意到下面代码:

.addEventListener('sharePressed', function (event) {
      ref.executeScript({ code: "getJumpData()" }, (params) => {
         console.log(JSON.stringify(params));
      });
});

在浏览器页面操作保存临时数据后,利用自定义原生按钮事件,把数据传递出来。

仅给出大致思路抛个砖,有兴趣的自行深挖吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容