// 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 接口,就实现了跨页返回。
三是将 C++ 的线程与 Lua 的线程对应起来,使用同一个 Lua VM,但在每个 C++ 线程中都用lua_newthread 创建一个 Lua 线程 State 指针。不过在创建线程那一刻,仍然需要对主 lua_State 加锁。这其实相当于给每个 C++ 线程都创建了一个独立的 Lua 堆栈,这样在传参和执行脚本的时候就不担心有数据冲突。理论上来讲效果应该与二是类似的。
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,我们也能获得一个可用的连接。
“过早优化是万恶之源。” 这是 Donald Knuth 的一句名言。虽然大部分人都不知道,或者会忘掉前面半句:“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.” Knuth 说出这句话时,可能想不到这句话会多么地流行,多么根植在很多人心中,以至于成为程序员偷懒的借口,阻碍进步的动力。因为有了这句话,在你指出别人代码中可以优化的问题时,还必须浪费口舌来解释这样的优化是必要的,不是过早优化或者过度优化。
还有一句名言“好代码本身就是最好的文档。当你需要添加一个注释时,你应该考虑如何修改代码才能不需要注释。” 这是 Steve McConnell 说的。同样,大部分人都不知道,或者忘掉后面半句:Good code is its own best documentation. As you're about to add a comment, ask yourself, "How can I improve the code so that this comment isn't needed?"Improve the code and then document it to make it even clearer. 如果你是程序员,回想一下多少次跟别人讨论代码是不是必须要注释时,这句话被引用到;有很多次在写代码时喜爱这句话,又多少次改别人的代码时痛恨这句话。
t0 = Timer ' 词典 Set map_dict = CreateObject("Scripting.Dictionary")
' 打开分中心映射表 Set map_sheet = Worksheets("分中心映射表")
map_nrows = map_sheet.Range("A300").End(xlUp).Row Set my_rows = map_sheet.Range("A2:B" & map_nrows).Rows
' 遍历分中心映射表,获得 分中心 对应的一级分中心,插入词典 ForEach my_row In my_rows
center = my_row.Cells(1, 1).Value
city = my_row.Cells(1, 2).Value IfNot map_dict.Exists(center) Then
map_dict.Add center, city EndIf Next my_row
' 打开机器表 Set dispatch_sheet = Worksheets("机器表")
dispatch_nrows = dispatch_sheet.Range("G99999").End(xlUp).Row Set my_rows = dispatch_sheet.Range("K2:L" & dispatch_nrows).Rows
' 遍历开通表,通过词典获得 machine_id 对应的一级分中心,插入开通表 ForEach o_row In my_rows
center = o_row.Cells(1, 1).Value
o_row.Cells(1, 2).Value = map_dict.Item(center) Next o_row
Encodings that are not ASCII based (such as UCS-2) are not allowed, and should be wrapped with codecs.getreader(encoding)(fp), or simply decoded to a unicode object and passed to loads().
日志的作用是提供信息,但不同的日志语句,提供的信息量却是不一样的。有的日志里会写“Failed to get sth..”,但却忘记加上失败调用的返回值。同程序一样,日志语句中有的是变量(某个变量内容),有的是常量(提示信息)。常量你总能从程序源代码中获得,但变量不行。所以在一条日志中,信息量最大的是变量,是函数返回值/字符串内容/错误码,因而变量应该尽量放在靠前的位置。常量也不是一点价值没有,写得好的提示语句,会使问题一目了然,可以免去你到代码中 grep,然后重读代码的麻烦。
所以我修改了一下 exVim 的代码,将默认的 dir filter 含义修改为匹配拒绝,即:“匹配 dir filter 的目录被拒绝(被过滤掉),无论它在哪一级。"例如,我将 dir filter 设置为 “test,output”,那么我项目目录下所有叫做 test 或者 output 的子目录都不会显示到项目目录列表中,而不妨碍其它名称目录的通过。
The members of a nested class have no special access to members of an enclosing class, nor to classes or functions that have granted friendship to an enclosing class; the usual access rules (clause 11) shall be obeyed. The members of an enclosing class have no special access to members of a nested class; the usual access rules (clause 11) shall be obeyed.
Example:
classE { int x; class B { }; classI {
B b; // error: E::B is private int y; void f(E* p, int i) {
p->x = i; // error: E::x is private
}
}; int g(I* p)
{ return p->y; // error: I::y is private
}
};
但是在 C++11 中,这段描述变更为:
$11.7/1 Nested classes [class.access.nest]
A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules (Clause 11) shall be obeyed.
Example:
classE { int x; class B { }; classI {
B b; // OK: E::I can access E::B int y; void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
}; int g(I* p) { return p->y; // error: I::y is private
}
};