前言

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

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

app 调用 h5 的代码

h5 调用 app 的代码

app 调用 h5 的代码

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

Javascript:

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

h5 调用 app 的代码

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

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

方法一:由 app 向 h5 注入一个全局 js 对象,然后在 h5 直接访问这个对象(addScriptMessageHandler)

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

android:

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;

}

@end

JSContext *context=[webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

AppSdk *appSdk = [AppSdk new];

context[@"appSdk"] = appSdk;

javascript:

window.appSdk.double(10); // 20

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

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

大致需要以下几个步骤:

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

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

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

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

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

javascript:

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;

}

参考:

h5 与原生 app 交互的原理

客户端相关知识学习(二)之h5与原生app交互的原理的更多相关文章

  1. h5 与原生 app 交互的原理

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

  2. 客户端相关知识学习(十二)之iOS H5交互Webview实现localStorage数据存储

    前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...

  3. 客户端相关知识学习(十一)之Android H5交互Webview实现localStorage数据存储

    前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...

  4. 客户端相关知识学习(十)之app给h5传递数据

    方法一: app可以把参数传到h5的链接里,用类似?xx=xx&xx=xx的形式拼接,js解析参数即可. 方法二: 情况一:app调用h5 原生app都可以对js的function进行触发,前 ...

  5. 客户端相关知识学习(三)之Android原生与H5交互的实现

    Android原生与H5交互的实现 H5调用原生的方式 方式可能有多种,根据开发经验,接触过两种方式. 方法一:Android向H5注入全局js对象,也就是H5调Android 1.首先对WebVie ...

  6. 客户端相关知识学习(一)之混合开发,为什么要在App中使用H5页面以及应用场景、注意事项

    混合开发 随着移动互联网的高速发展,常规的开发速度已经渐渐不能满足市场需求.原生H5混合开发应运而生,目前,市场上许多主流应用都有用到混合开发,例如支付宝.美团等.下面,结合我本人的开发经验,简单谈一 ...

  7. 客户端相关知识学习(九)之h5给app传递数据

    方法一: 情况一: if (window.JdAndroid){          window.JdAndroid.setPayCompleted();          window.JdAndr ...

  8. 客户端相关知识学习(四)之H5页面如何嵌套到APP中

    Android原生如何渲染H5页面 Android与 H5 的交互方式大概有以下 1 种: 利用WebView进行交互(系统API) iOS原生如何渲染H5页面 iOS 与 H5 的交互方式大概有以下 ...

  9. 客户端相关知识学习(六)之deeplink技术

    Deeplink应用描述 Deeplink,简单讲,就是你在手机上点击一个链接之后,可以直接链接到app内部的某个页面,而不是app正常打开时显示的首页.不似web,一个链接就可以直接打开web的内页 ...

随机推荐

  1. window环境下 恢复odoo数据库备份文件时产生的 Database restore error: Command `psql` not found.

    1,首先先查看 PostgreSQL 是否安装在C盘,如果安装在其他盘 则需要配置环境变量 配置完成后重启服务就可以了 2, 如果还不行,只需在odoo.conf中添加一个配置设置.也就是在odoo项 ...

  2. LeetCode 260. 只出现一次的数字 III(Single Number III)

    题目描述 给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次. 找出只出现一次的那两个元素. 示例 : 输入: [1,2,1,3,2,5] 输出: [3,5] 注意: 结 ...

  3. LeetCode 80. 删除排序数组中的重复项 II(Remove Duplicates from Sorted Array II)

    题目描述 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ...

  4. React 番外篇

    小技巧:如果我们想了解一门技术,不知道如何学习,那就在 BOSS 直聘上,来看看对这门技术的要求 这篇给大家讲的是 React 1.0 的初始版本,仅仅是让大家有个了解,毕竟回顾历史,我们才能找到他最 ...

  5. war包的解压与打包

    转: war包的解压与打包 2018年03月22日 14:59:56 Jitwxs 阅读数:21421   版权声明:本文版权归Jitwxs所有,欢迎转载,但未经作者同意必须保留原文链接. https ...

  6. CentOS6.8安装Oracle11g

    ===== 这中间还有很多细节问题该文档中并没有说明和指出: 1.如/tmp目录必须单独分出来,不然oracle在以后的使用中会逐渐变慢 2.官网说的512M内存即可,这里纠正下,如果只是测试安装那还 ...

  7. Spring mvc中@RequestMapping 基本用法

    @RequestMapping(value="/departments") public String simplePattern(){ System.out.println(&q ...

  8. JavaScript基础之数组常用方法

    目录 JS 数组常用API 常用属性 常用方法 常见方法语法解释 from方法 isArray concat every fill filter find forEach indexOf join k ...

  9. linux上wps2019不能启动解决方法

    本人linux上的wps2016升级成wps2019后启动不了,双击图标没反应,在命令行输入wps,提示"/lib64/libc.so.6: version `GLIBC_2.18' not ...

  10. ASP.NET Core 入门笔记2,建立项目

    1.建立项目 2.项目结构 1.项目结构说明 根目录/文件 说明 .vscode目录 VS Code项目配置目录,相当于.vs..idea文件夹 bin目录 编译输出目录 obj目录 编译配置与中间目 ...