前言

现在移动端 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. C++入门经典-例7.7-对象与复制,菌类的繁殖

    1:当函数以相应的类作为形参列表时,对象可以作为函数的参数传入.在学习函数时,我们曾提过,值传递先复制实参产生副本.那么对象的副本是怎样的呢? 复制构造函数是指类的对象被复制时所调用的函数.下面两种情 ...

  2. 搞清楚MySQL事务隔离级别

    首先创建一个表 account.创建表的过程略过(由于 InnoDB 存储引擎支持事务,所以将表的存储引擎设置为 InnoDB).表的结构如下: 然后往表中插入两条数据,插入后结果如下: 为了说明问题 ...

  3. How to change the button text of <input type=“file” />?

    How to change the button text of <input type=“file” />? Simply <label class="btn btn-p ...

  4. koa 基础(二十三)封装 DB 库 --- 应用

    1.根目录/module/config.js /** * 配置文件 */ var app = { dbUrl: 'mongodb://127.0.0.1:27017/?gssapiServiceNam ...

  5. Mysql中两个select语句的连接

    Mysql中两个select语句连接需要用到操作符 SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥 ...

  6. 使用Statement执行DML和DQL语句

    import com.loaderman.util.JdbcUtil; import java.sql.Connection; import java.sql.DriverManager; impor ...

  7. 吐血整理,一文读懂中国金融衍生品市场的前世今生和未来[z]

    [z]https://www.gfedu.cn/cfrm/content_22687.shtml 从定义上来说,金融衍生工具(derivativesecurity)是在货币.债券.股票等传统金融工具的 ...

  8. 整型,长整型,无符号整型等 大端和小端(Big endian and Little endian)

    一.大端和小端的问题 对于整型.长整型.无符号整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian ...

  9. python解压压缩包

    默认解压到当前目录 import shutil shutil.unpack_archive('/root/redis-3.2.3.tar.gz') 解压到home目录下 import shutil s ...

  10. phpstorm 远程连接服务器进行开发

    phpstorm phpstorm是一款功能强大的ide编辑器,有了它,你敲代码速度能比用notepad++快数倍(初学者不建议使用ide,建议使用notepad++),缺点是没有固态的电脑带起来吃力 ...