h5 与原生 app 交互的原理



作者:senntyou

segmentfault.com/a/1190000016759517


现在移动端 web 应用,很多时候都需要与原生 app 进行交互、沟通(运行在 webview中),比如微信的 jssdk,通过 window.wx 对象调用一些原生 app 的功能。所以,这次就来捋一捋 h5 与原生 app 交互的原理。

h5 与原生 app 的交互,本质上说,就是两种调用:

  1. app 调用 h5 的代码

  2. h5 调用 app 的代码

1. app 调用 h5 的代码

因为 app 是宿主,可以直接访问 h5,所以这种调用比较简单,就是在 h5 中曝露一些全局对象(包括方法),然后在原生 app 中调用这些对象。

640?wx_fmt=pngjavascript:

window.sdk = {  double = value => value * 2,  triple = value => value * 3,};

android:

webview.evaluateJavascript('window.sdk.double(10)', new ValueCallback<String>() {  @Override  public void onReceiveValue(String s) {    // 20  }});

ios:

NSString *func = @"window.sdk.double(10)";NSString *str = [webview stringByEvaluatingJavaScriptFromString:func]; // 20

2. h5 调用 app 的代码

因为 h5 不能直接访问宿主 app,所以这种调用就相对复杂一点。

这种调用常用有两种方式:

  1. 由 app 向 h5 注入一个全局 js 对象,然后在 h5 直接访问这个对象

  2. 由 h5 发起一个自定义协议请求,app 拦截这个请求后,再由 app 调用 h5 中的回调函数

2.1 由 app 向 h5 注入一个全局 js 对象

这种方式沟通机制简单,比较好理解,并且对于 h5 来说,没有新的东西,所以是比较推荐的一种方式。但这种方式可能存在安全隐患,详细查看 你不知道的 Android WebView 使用漏洞。

640?wx_fmt=pngandroid:

webview.addJavascriptInterface(new Object() {  @JavascriptInterface  public int double(value) {    return value * 2;  }  @JavascriptInterface  public int triple(value) {    return value * 3;  }}, "appSdk");

ios:

@interface AppSdk : NSObject{}- (int) double:(int)value;- (int) triple:(int)value;@end@implementation AppSdk- (int) double:(int)value {  return value * 2;}- (int) triple:(int)value {  return value * 3;}@endJSContext *context=[webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];AppSdk *appSdk = [AppSdk new];context[@"appSdk"] = appSdk;

javascript:

window.appSdk.double(10); // 20
2.2 由 h5 发起一个自定义协议请求

这种方式要稍复杂一点,因为需要自定义协议,这对很多前端开发者来说是比较新的东西。所以一般不推荐这种方式,可以作为第一种方式的补充。

大致需要以下几个步骤:

  1. 由 app 自定义协议,比如 sdk://action?params

  2. 在 h5 定义好回调函数,比如 window.bridge={getDouble:value=>{},getTriple:value=>{}}

  3. 由 h5 发起一个自定义协议请求,比如 location.href='sdk://double?value=10'

  4. app 拦截这个请求后,进行相应的操作,获取返回值

  5. 由 app 调用 h5 中的回调函数,比如 window.bridge.getDouble(20);

640?wx_fmt=pngjavascript:

window.bridge = {  getDouble: value => {    // 20  },   getTriple: value => {    // more    }};location.href = 'sdk://double?value=10';

android:

webview.setWebViewClient(new WebViewClient() {    @Override    public boolean shouldOverrideUrlLoading(WebView view, String url) {        // 判断如果 url 是 sdk:// 打头的就拦截掉        // 然后从 url sdk://action?params 中取出 action 与params         Uri uri = Uri.parse(url);                                         if ( uri.getScheme().equals("sdk")) {            // 比如 action = double, params = value=10            webview.evaluateJavascript('window.bridge.getDouble(20)');            return true;        }        return super.shouldOverrideUrlLoading(view, url);    }});

ios:

- (BOOL)webview:(UIWebView *)webview shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {  // 判断如果 url 是 sdk:// 打头的就拦截掉  // 然后从 url sdk://action?params 中取出 action 与params  NSString *urlStr = request.URL.absoluteString;  if ([urlStr hasPrefix:@"sdk://"]) {    // 比如 action = double, params = value=10    NSString *func = @"window.bridge.getDouble(20)";    [webview stringByEvaluatingJavaScriptFromString:func];    return NO;  }  return YES;}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(原)直方图的相似性度量

转载请注明出处&#xff1a; http://www.cnblogs.com/darkknightzh/p/5147982.html 对于两直方图 $S\left\{ {{s}_{1}},\cdots {{s}_{n}} \right\}$ 及 $M\left\{ {{m}_{1}},\cdots {{m}_{n}} \right\}$&#xff0c;n为直方图维数&#xff08;如255&#xff09;&#xff0c;这两…

【ROS问题】rqt_plot运行报错

本人Linux版本&#xff1a;Ubuntu 18.04 LTS ROS版本&#xff1a;Melodic 方案一&#xff1a; 你看那个报错&#xff0c;全是Matplotlib的报错&#xff0c;是这个东西版本不够高&#xff0c;重新安装就好啦。 python -m pip install -U pip python -m pip install -U matp…

BCP使用笔记整理

一、BCP 简介大容量复制程序实用工具 (bcp) 可以在 Microsoft SQL Server 实例和用户指定格式的数据文件间大容量复制数据。 使用 bcp 实用工具可以将大量新行导入 SQL Server 表&#xff0c;或将表数据导出到数据文件。 除非与 queryout 选项一起使用&#xff0c;否则使用该实…

怎样基于谷歌地图的Server缓存公布Image Service服务

怎样基于谷歌地图的Server缓存公布Image Service服务第一步&#xff1a;下载地图数据下载安装水经注万能地图下载器&#xff0c;启动时仅仅选择电子.谷歌&#xff08;这里能够依据自己的须要选择&#xff09;。例如以下图所看到的。找到成都后框选下载成都区域&#xff0c;例如…

ROS文件系统介绍

预备工作 本教程中我们将会用到ros-tutorials程序包&#xff0c;请先安装&#xff1a; sudo apt-get install ros-<distro>-ros-tutorials快速了解文件系统概念 Packages: 软件包&#xff0c;是ROS应用程序代码的组织单元&#xff0c;每个软件包都可以包含程序库、可执…

接软件开发项目,你需要知道这些!

作为一个程序员&#xff0c;跟客户交流是最困难的事情了&#xff0c;所以在上路之前&#xff0c;复习一下这两年遇到的奇怪的客户言论&#xff0c;以便以后更好地跟客户交流。1、不就是做个网站&#xff08;或者别的&#xff09;么&#xff1f;为什么这么贵&#xff1f;一定耐心…

整理的一些比较基础的面试知识点

1、面向对象的三大特性或其具体体现在哪 2、页面间传值方式 3、session cookie原理及区别 4、hasstable&#xff0c;dictionary&#xff0c;List &#xff0c;collection 5、类和抽象类&#xff0c;类和接口&#xff0c;接口和抽象类区别及适合场景 6、Get和Post比较优缺点或区…

五种类型的程序员,你属于哪一种?

在我的编程生涯中,我碰到过很多奇奇怪怪的对手和同盟。我把这些编码战士们分成五类&#xff0c;有些人是你队伍中的好伙伴&#xff0c;有些人则是捣蛋者&#xff0c;让你的每一个计划都完不成。不管怎么说&#xff0c;他们在软件开发的诸神殿上都占有一席之地。如果你的团队中没…

创建ROS程序包

一个catkin程序包由什么组成? 一个程序包要想称为catkin程序包必须符合以下要求&#xff1a; 该程序包必须包含catkin compliant package.xml文件这个package.xml文件提供有关程序包的元信息。 程序包必须包含一个catkin 版本的CMakeLists.txt文件&#xff0c;而Catkin meta…

一些有用的js插件

getfuelux.com 一系列插件合集 Ion.RangeSlider 超级牛的范围选择控件 Ion.CheckRadio Ion.Tabs Ion.Calendar Ion.ImageSlider Ion.Zoom www.ngwidgets.com Advanced UI Widgets for AngularJS http://www.jq22.com/ jQuery 插件库 http://jvectormap.com/ 地图插件 X-…

C# FTP操作类库

class FTP_Class{string ftpServerIP;string ftpUserID;string ftpPassword;FtpWebRequest reqFTP; #region 连接/// <summary>/// 连接FtpWebRequest/// </summary>/// <param name"path"></param>private void Connect(String path)/…

安装并配置ROS环境

参考该网址内容&#xff1a;http://wiki.ros.org/cn/ROS/Tutorials/InstallingandConfiguringROSEnvironment

Cropper – 简单的 jQuery 图片裁剪插件

Cropper 是一个简单的 jQuery 图像裁剪插件。它支持选项&#xff0c;方法&#xff0c;事件&#xff0c;触摸&#xff08;移动&#xff09;&#xff0c;缩放&#xff0c;旋转。输出的裁剪数据基于原始图像大小&#xff0c;这样你就可以用它们来直接裁剪图像。 如果你尝试裁剪跨域…

C# JSON格式数据用法

JSON简介JSON(全称为JavaScript ObjectNotation) 是一种轻量级的数据交换格式。它是基于JavaScript语法标准的一个子集。JSON采用完全独立于语言的文本格式&#xff0c;可以很容易在各种网络、平台和程序之间传输。JSON的语法很简单&#xff0c;易于人阅读和编写&#xff0c;同…

Ros命令及功能

运行小乌龟代码&#xff1a; roscore rosrun turtlesim turtlesim_node rosrun turtlesim turtle_teleop_key一些命令及作用 ros 加tap //查看电脑中以ros开头的命令 rqt_graph //将系统内的主要资源以可视化的形式展现出来 rosnode list //列出系统节点 命令 --help //查看命…

数据库——环境初建改端口和密码(转)

一、修改APACHE的监听端口 2、在界面中选apache&#xff0c;弹出隐藏菜单选项&#xff0c;打开配置文件httpd.conf; 2、找到Listen 80 和 ServerName localhost:80; 3、将80改成801&#xff08;当然自己也可以设定别的不使用的端口&#xff0c;例如8000等&#xff09;; 4、保存…

文件系统认知

什么是文件系统 常规认知是&#xff1a;linux根目录那些东西 百科&#xff1a;文件系统是操作系统用于明确存储设备组织文件的方法&#xff0c;操作系统中负责管理和存储文件信息的软件机构称为文件管理系统&#xff0c;简称文件系统。 以上说的方法&#xff1a;就是文件管理…

何谓悲观锁与乐观锁

乐观锁对应于生活中乐观的人总是想着事情往好的方向发展&#xff0c;悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点&#xff0c;不能不以场景而定说一种人好于另外一种人。 悲观锁 总是假设最坏的情况&#xff0c;每次去拿数据的时候都认为别人会…

寒哥细谈之AutoLayout全解

看到群中好多朋友还停留在Frame布局的痛苦时代&#xff0c;以及有些开发者接手别人的就项目发现布局一团乱。而且没有启动图的时候并不是真正真正适配iPhone 6(S)、iPhone6(S) Plus等设备 。寒哥准备尽可能详细的讲一讲我所掌握的AutoLayout 。AutoLayout很难&#xff1f;我觉得…

最难学的5种编程语言排行

每个程序员都熟悉许多编程语言。许多编程语言都是高级的&#xff0c;它们的语法是人类可读的。然而&#xff0c;也有一些低级语言&#xff0c;对于一个人来说&#xff0c;读起来很困难&#xff0c;但是可以理解。然而&#xff0c;您是否遇到过一种既不可读又不可理解的编程语言…