// Java: 定义一个类,提供一个接口,返回一个内容
class NativeApis {
@JavascriptInterface
public String propose(String msg) {
return "Yes!";
}
}
webView.addJavascriptInterface(new NativeApis(), "Bridge");
// Javascript: 执行一个 native 的方法
alert(window.Bridge.propose("Will you merry me?"));
但问题在于在 API 17 (Android 4.2) 之前这个方法存在安全漏洞,攻击者可以执行任意代码。在 API 17 及以后,通过显式地给出 @JavascriptInterface 限定暴露的接口,避免了安全漏洞。但在 API 17 以前,不建议使用此方法,可以考虑下面的 work around。
主动发起与 JS 的交互场景比较少,可以有两种方法实现:一种是页面加载过程中将回调注册给 NA;另一种是通过 Web Event 的方式由 NA 广播给 JS 上下文。我们更建议通过 Web Event 的方式广播,这样不受页面加载状态之类的限制,交互上更简单。当然,也可以两种方法结合,增加一个 Event 到 NA 的注册,保证有效广播。
被动的回调 JS,实现上比较直观,只要在 JS 调用 NA 的接口中增加一个 callback 参数,NA 在完成之后回调记录下来的接口即可。
可能是为了性能或者设计使然,push 的时候不会销毁当前页。也就是说,在 A 页面里 push 跳转到B 页面,不会 Unmount A 页面的Component。 不过在 B 页面 pop 回 A 页面时,的确会 Unmount B 页面的Component。这也意味着,整个导航路径是一个页面堆栈,只要在堆栈里页面的 Component,都不会被 Unmount。
跳转的过程中有 A,但返回的时候要跳过 A,相当于可以自己操作 pop 的步长。很遗憾,react-native-navigation 没有提供这样的接口。不过我们可以采用一个 trick 的手段,来实现这个逻辑。
假设从 Root->A->B,在 A 的 state 里放一个 relayPop ,默认是 false。 在 A 跳转到 B 时,通过 props 传入一个回调:setParentRelayPop,B 可以通过这个回调修改 A 的 state relayPop 为 true; 在 A 的 willAppear 中,首先判断 relayPop 是否为真,如果是真的话,代表是从 B 返回且 B 要求接力返回,那么 A 就直接 pop 返回到 A 的上级。 B 在返回时,首先通过回调设置 relayPop 为 true,然后再调用 pop 接口,就实现了跨页返回。
These challenges always lead me to learn more than I expected, and this one also gave me a better sense of all the internal technology Facebook engineers get to use, as well as a thorough overview of home automation.
注意到这些酷炫的技术,都是 internal technology Facebook engineers get to use。那么到底有没有可能,使用公开领域的服务,构建一个类似于 Jarvis 的系统呢?
就像 Zuckerberg 所说“In a way, AI is both closer and farther off than we imagine. ”虽然很多人并没有意识到语音交互这类 AI 技术能够那么地触手可及,但技术的开放对 AI 应用普及的影响是巨大的。在这一点上,国内的人工智能产业巨头们做得并不差。这篇文章,WhatIsWhat 这个 APP,只能帮你迈出第一步,希望不远的将来,我们能够有更多的开放 AI 服务,使得搭建自己的专属 Jarvis 变成一件轻而易举的事情。
Change the way we cope with stale pooled connections.
Previously we'd attempt to detect if a connection was stale by
probing it. This was expensive (it relied on catching a 1-millisecond
read timing out with a SocketTimeoutException), and racy. If the
recycled connection was stale, the application would have to catch
the failure and retry.
The new approach is to try the stale connection directly and to recover
if that connection fails. This is simpler and avoids the isStale
heuristics.
This fixes some flakiness in URLConnectionTest tests like
testServerShutdownOutput and testServerClosesOutput.
Bug: http://b/2974888
Change-Id: I1f1711c0a6855f99e6ff9c348790740117c7ffb9
既然底层不重试,那么只有在应用层重试,所以我们在应用层增加了最多『http.maxConnections+1』次重试机制,以修复此问题。在重试的时候,尝试使用一个 stale connection 会导致 EOFException,底层也会自动关闭这个连接。『http.maxConnections+1』次重试保证即使连接池中全都是 stale connection,我们也能获得一个可用的连接。
Google 在移动平台(Android 和 iOS)上提供了独立的 Search App,但它不仅仅是用一个移动浏览器封装了 Google Web Search,而是做了很多移动应用相关的改进。这个系列文章,通过抓包对 Android Google App 与 Server 间通讯协议进行简单分析,管中窥豹,以见一斑。
减少一次搜索请求开销。从逻辑上讲,应该先进行语音识别,再用识别出的 Query 发起搜索。但 Google 把这一步放在了服务端,不需要用户再发起一次搜索结果的 GET 请求。因为 Google Search 的域名和 locale 有关,新的 GET 请求可能需要发给 google.com.hk,这就需要 App 新建一个 HTTPS 连接,开销还是比较大的。而且服务器端还可以进一步优化,比如在识别出中间结果的同时请求即时搜索,不知道 Google 有没有做。
Google 在移动平台(Android 和 iOS)上提供了独立的 Search App,但它不仅仅是用一个移动浏览器封装了 Google Web Search,而是做了很多移动应用相关的改进。这个系列文章,通过抓包对 Android Google App 与 Server 间通讯协议进行简单分析,管中窥豹,以见一斑。
Google Service 已经全面普及了 HTTPS 接入,所以想探索 Google 的通讯协议,首先必备的是 HTTPS 抓包能力。所谓的 HTTPS 抓包,实质上是通过代理服务器实现对测试手机上 HTTPS 连接的中间人攻击,所以必须在测试手机上安装代理服务器的 CA 证书,才能保证测试手机相信 HTTPS 连接是安全的。
当 IS 应答消息里有搜索结果时,点击搜索按钮不会再发起一次搜索。但如果 IS 应答只有 SUG,没有搜索结果,Google App 就会发起一次非 IS 的正常搜索请求。这次请求除了请求的 URL path 从 "/s" 变成 "/search" 以外,主要的 GET 参数保持一致,会有部分附加参数的不同。以『上海天气』(有 IS 结果)和『上海天气好不好呢』(无 IS 结果)为例,GET 参数有以下区别:
而非 IS 搜索应答和 IS 应答对比,区别主要在于非 IS 搜索应答消息中,没有搜索词 SUG Message 包。
协议分析和启发
请求消息协议
搜索请求是通过 GET 协议实现的,所以请求主要分为两部分:HTTP 头和 GET 参数。从请求上来看,Google 对 GET 参数的使用是非常节省的,很多字段都是极其精简的缩写。但它倒是在 HTTP 头里放了很多比较大的数据字段,从 Header 名来猜测,应该是跟设备、登录用户相关的一些加密字段。
因为搜索请求是 App 发出的,所以理论上 GET 请求和 POST 请求的实现难度是差不多的,POST 的时候可以进行数据压缩,Header 倒是不能压缩(HTTP 1.x)。那为什么 Google 反而选择把这么长的数据放在 HTTP Header 里呢?我的猜测是为了充分利用 HTTP/2 的特性。在 HTTP/2 里有个特性,叫做 Header Compression,在多次请求时,同一个 Header 原文仅需要压缩传输一次即可。但由于现在还没有 HTTP/2 的抓包工具,所以还无法判断 Google App 是已经用上了这个特性,还是为未来的使用做好准备。不过这至少给了我们一个启发,为了充分利用底层协议的特性,应用层约定可能也需要一些适配工作。
应答消息协议
Google App 的搜索结果,并没有像普通网站服务一样,直接用标准的 HTML 协议返回一个 Web Page。而是将渲染好的 Web Page 分段放到应答消息中,由 App 端提取、拼接成最终的搜索结果页。猜测有以下几点考虑: