Web 与 原生交互
- 同步,会阻塞线程
- UIWebView JavaScriptCore
- stringByEvaluatingJavaScriptFromString
原生注册 方法
WKUserContentController *userContentController = [WKUserContentController new];
[userContentController addScriptMessageHandler:self name:<name>];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.userContentController = userContentController;
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.bounds configuration:config];
JS 往 方法发送数据
window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
允许的类型 number string date array object null
[_webView evaluateJavaScript:source completionHandler:nil];
- callWithArguments
- 4.2 以下 addJavascriptInterface 有安全隐患
参考
原生注册方法
webview.addJavascriptInterface(new JSKit(),"__context__");
public class JSKit {
// 定义JS需要调用的方法,被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public void hello(String msg) {
System.out.println("JS成功调用了Android的hello方法");
}
}
JS 调用原生方法
window.__context__.hello('msg');
-
Android JsBridge 自定义
window.WebViewJavascriptBridge
方式实现 -
iOS WebViewJavascriptBridge iframe 中
https://__bridge_loaded__
实现
JsBridge 和 WebViewJavascriptBridge 实现的原理:
- Web > 原生:
原生监听 URL > Web 请求对应 URL,并定义唯一ID,监听对应ID的响应 > 原生收到 URL 后,做相应响应发起对应唯一ID的 URL 请求 > Web 响应回调
- 原生 > Web:
Web 监听 URL > 原生 请求对应 URL,并定义唯一ID,监听对应ID的响应 > Web 收到请求后,做相应响应发起对应唯一ID的 URL 回调 > 原生 响应回调
- 相比 JS 调 原生,全平台统一
- 无回调,没有阻塞线程问题
- 只适用于 Web 调 原生
- 所有跳转都会判断是否满足要求
- 不支持链接会 404
- 没有回调
在该方法替换返回数据
@Override publicboolean shouldOverrideUrlLoading(WebView view,String
url)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
- 最好用自定义 scheme 的方式处理
- 相比 URL 会引起页面刷新
- 相比 URL 有回调
- 相比 JS 异步、接口统一
- 只适用于 Web 调 原生
没有办法再shouldOverrinding
中拦截并用webView.loadUrl(String url,HashMap headers)
方法添加请求头
一个临时的办法解决:
首先需要在url中加特殊标记/协议, 如在onWebViewResource
方法中拦截对应的请求,然后将要添加的请求头,以get形式拼接到url末尾
在shouldInterceptRequest()
方法中,可以拦截到所有的网页中资源请求,比如加载JS,图片以及Ajax请求等等
使用 NSURLProtocol
实现
参考
- Cross-platform(CLI) workflow : CLI是一个High-Level的工具,可以允许你在多个平台上只建立一次工程。
- Platform-centered workflow : 以Native为中心,使用WebView的形式嵌入。
使用基于 VUE 的 UI 库
可以结合一起用,取长补短
使用 基于 AngularJS 的 UI 库
数据少时用 localstorage
,数据多时用 SQLite
- cordova-hot-code-push 热更新插件
- ordova-hot-code-push-cli cordova-hot-code-push 命令行工具, 热更新服务器
- cordova-app-loader 热更新插件-只更新修改部分
这种方式热更新不会被苹果拒
- 苹果不让用
4.4 以下 WebView 用的 WebKit 内核,性能很差
性能最好,但是太大
不过我建议使用腾讯的X5内核,我项目目前在使用,腾讯浏览服务,你不用把整个内核集成到你的APP去,而是如果你的手机有安装手机QQ或者微信,它就会自行调用他们的内核,另外现在还提供下载内核的功能。项目使用以来没有出现什么大问题,平稳使用中。
18.请问下x5中js调用android怎么实现?
跟系统内核下一样,都借助 addjavainterface 实现